1 /*
  2  * Copyright (c) 2018, 2025, Oracle and/or its affiliates. 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 #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);
145   } else if (bytes == 16) {
146     assert(dst2 != noreg, "invariant");
147     assert(dst2 != dst1, "invariant");
148     __ ldp(dst1, dst2, src);
149   } else {
150     // Not the right size
151     ShouldNotReachHere();
152   }
153   if ((decorators & ARRAYCOPY_CHECKCAST) != 0 && UseCompressedOops) {
154     __ decode_heap_oop(dst1);
155   }
156 }
157 
158 void BarrierSetAssembler::copy_store_at(MacroAssembler* masm,
159                                         DecoratorSet decorators,
160                                         BasicType type,
161                                         size_t bytes,
162                                         Address dst,
163                                         Register src1,
164                                         Register src2,
165                                         Register tmp1,
166                                         Register tmp2,
167                                         Register tmp3) {
168   if ((decorators & ARRAYCOPY_CHECKCAST) != 0 && UseCompressedOops) {
169     __ encode_heap_oop(src1);
170   }
171   if (bytes == 1) {
172     assert(src2 == noreg, "invariant");
173     __ strb(src1, dst);
174   } else if (bytes == 2) {
175     assert(src2 == noreg, "invariant");
176     __ strh(src1, dst);
177   } else if (bytes == 4) {
178     assert(src2 == noreg, "invariant");
179     __ strw(src1, dst);
180   } else if (bytes == 8) {
181     assert(src2 == noreg, "invariant");
182     __ str(src1, dst);
183   } else if (bytes == 16) {
184     assert(src2 != noreg, "invariant");
185     assert(src2 != src1, "invariant");
186     __ stp(src1, src2, dst);
187   } else {
188     // Not the right size
189     ShouldNotReachHere();
190   }
191 }
192 
193 void BarrierSetAssembler::copy_load_at(MacroAssembler* masm,
194                                        DecoratorSet decorators,
195                                        BasicType type,
196                                        size_t bytes,
197                                        FloatRegister dst1,
198                                        FloatRegister dst2,
199                                        Address src,
200                                        Register tmp1,
201                                        Register tmp2,
202                                        FloatRegister vec_tmp) {
203   if (bytes == 32) {
204     __ ldpq(dst1, dst2, src);
205   } else {
206     ShouldNotReachHere();
207   }
208 }
209 
210 void BarrierSetAssembler::copy_store_at(MacroAssembler* masm,
211                                         DecoratorSet decorators,
212                                         BasicType type,
213                                         size_t bytes,
214                                         Address dst,
215                                         FloatRegister src1,
216                                         FloatRegister src2,
217                                         Register tmp1,
218                                         Register tmp2,
219                                         Register tmp3,
220                                         FloatRegister vec_tmp1,
221                                         FloatRegister vec_tmp2,
222                                         FloatRegister vec_tmp3) {
223   if (bytes == 32) {
224     __ stpq(src1, src2, dst);
225   } else {
226     ShouldNotReachHere();
227   }
228 }
229 
230 void BarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
231                                                         Register obj, Register tmp, Label& slowpath) {
232   // If mask changes we need to ensure that the inverse is still encodable as an immediate
233   STATIC_ASSERT(JNIHandles::tag_mask == 0b11);
234   __ andr(obj, obj, ~JNIHandles::tag_mask);
235   __ ldr(obj, Address(obj, 0));             // *obj
236 }
237 
238 // Defines obj, preserves var_size_in_bytes, okay for t2 == var_size_in_bytes.
239 void BarrierSetAssembler::tlab_allocate(MacroAssembler* masm, Register obj,
240                                         Register var_size_in_bytes,
241                                         int con_size_in_bytes,
242                                         Register t1,
243                                         Register t2,
244                                         Label& slow_case) {
245   assert_different_registers(obj, t2);
246   assert_different_registers(obj, var_size_in_bytes);
247   Register end = t2;
248 
249   // verify_tlab();
250 
251   __ ldr(obj, Address(rthread, JavaThread::tlab_top_offset()));
252   if (var_size_in_bytes == noreg) {
253     __ lea(end, Address(obj, con_size_in_bytes));
254   } else {
255     __ lea(end, Address(obj, var_size_in_bytes));
256   }
257   __ ldr(rscratch1, Address(rthread, JavaThread::tlab_end_offset()));
258   __ cmp(end, rscratch1);
259   __ br(Assembler::HI, slow_case);
260 
261   // update the tlab top pointer
262   __ str(end, Address(rthread, JavaThread::tlab_top_offset()));
263 
264   // recover var_size_in_bytes if necessary
265   if (var_size_in_bytes == end) {
266     __ sub(var_size_in_bytes, var_size_in_bytes, obj);
267   }
268   // verify_tlab();
269 }
270 
271 static volatile uint32_t _patching_epoch = 0;
272 
273 address BarrierSetAssembler::patching_epoch_addr() {
274   return (address)&_patching_epoch;
275 }
276 
277 void BarrierSetAssembler::increment_patching_epoch() {
278   Atomic::inc(&_patching_epoch);
279 }
280 
281 void BarrierSetAssembler::clear_patching_epoch() {
282   _patching_epoch = 0;
283 }
284 
285 void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm, Label* slow_path, Label* continuation, Label* guard) {
286   BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
287 
288   Label local_guard;
289   Label skip_barrier;
290   NMethodPatchingType patching_type = nmethod_patching_type();
291 
292   if (slow_path == nullptr) {
293     guard = &local_guard;
294   }
295 
296   // If the slow path is out of line in a stub, we flip the condition
297   Assembler::Condition condition = slow_path == nullptr ? Assembler::EQ : Assembler::NE;
298   Label& barrier_target = slow_path == nullptr ? skip_barrier : *slow_path;
299 
300   __ ldrw(rscratch1, *guard);
301 
302   if (patching_type == NMethodPatchingType::stw_instruction_and_data_patch) {
303     // With STW patching, no data or instructions are updated concurrently,
304     // which means there isn't really any need for any fencing for neither
305     // data nor instruction modifications happening concurrently. The
306     // instruction patching is handled with isb fences on the way back
307     // from the safepoint to Java. So here we can do a plain conditional
308     // branch with no fencing.
309     Address thread_disarmed_addr(rthread, in_bytes(bs_nm->thread_disarmed_guard_value_offset()));
310     __ ldrw(rscratch2, thread_disarmed_addr);
311     __ cmp(rscratch1, rscratch2);
312   } else if (patching_type == NMethodPatchingType::conc_instruction_and_data_patch) {
313     // If we patch code we need both a code patching and a loadload
314     // fence. It's not super cheap, so we use a global epoch mechanism
315     // to hide them in a slow path.
316     // The high level idea of the global epoch mechanism is to detect
317     // when any thread has performed the required fencing, after the
318     // last nmethod was disarmed. This implies that the required
319     // fencing has been performed for all preceding nmethod disarms
320     // as well. Therefore, we do not need any further fencing.
321     __ lea(rscratch2, ExternalAddress((address)&_patching_epoch));
322     // Embed an artificial data dependency to order the guard load
323     // before the epoch load.
324     __ orr(rscratch2, rscratch2, rscratch1, Assembler::LSR, 32);
325     // Read the global epoch value.
326     __ ldrw(rscratch2, rscratch2);
327     // Combine the guard value (low order) with the epoch value (high order).
328     __ orr(rscratch1, rscratch1, rscratch2, Assembler::LSL, 32);
329     // Compare the global values with the thread-local values.
330     Address thread_disarmed_and_epoch_addr(rthread, in_bytes(bs_nm->thread_disarmed_guard_value_offset()));
331     __ ldr(rscratch2, thread_disarmed_and_epoch_addr);
332     __ cmp(rscratch1, rscratch2);
333   } else {
334     assert(patching_type == NMethodPatchingType::conc_data_patch, "must be");
335     // Subsequent loads of oops must occur after load of guard value.
336     // BarrierSetNMethod::disarm sets guard with release semantics.
337     __ membar(__ LoadLoad);
338     Address thread_disarmed_addr(rthread, in_bytes(bs_nm->thread_disarmed_guard_value_offset()));
339     __ ldrw(rscratch2, thread_disarmed_addr);
340     __ cmpw(rscratch1, rscratch2);
341   }
342   __ br(condition, barrier_target);
343 
344   if (slow_path == nullptr) {
345     __ lea(rscratch1, RuntimeAddress(StubRoutines::method_entry_barrier()));
346     __ blr(rscratch1);
347     __ b(skip_barrier);
348 
349     __ bind(local_guard);
350 
351     __ emit_int32(0);   // nmethod guard value. Skipped over in common case.
352   } else {
353     __ bind(*continuation);
354   }
355 
356   __ bind(skip_barrier);
357 }
358 
359 void BarrierSetAssembler::c2i_entry_barrier(MacroAssembler* masm) {
360   Label bad_call;
361   __ cbz(rmethod, bad_call);
362 
363   // Pointer chase to the method holder to find out if the method is concurrently unloading.
364   Label method_live;
365   __ load_method_holder_cld(rscratch1, rmethod);
366 
367   // Is it a strong CLD?
368   __ ldrw(rscratch2, Address(rscratch1, ClassLoaderData::keep_alive_ref_count_offset()));
369   __ cbnz(rscratch2, method_live);
370 
371   // Is it a weak but alive CLD?
372   __ push(RegSet::of(r10), sp);
373   __ ldr(r10, Address(rscratch1, ClassLoaderData::holder_offset()));
374 
375   __ resolve_weak_handle(r10, rscratch1, rscratch2);
376   __ mov(rscratch1, r10);
377   __ pop(RegSet::of(r10), sp);
378   __ cbnz(rscratch1, method_live);
379 
380   __ bind(bad_call);
381 
382   __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
383   __ bind(method_live);
384 }
385 
386 void BarrierSetAssembler::check_oop(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2, Label& error) {
387   // Check if the oop is in the right area of memory
388   __ mov(tmp2, (intptr_t) Universe::verify_oop_mask());
389   __ andr(tmp1, obj, tmp2);
390   __ mov(tmp2, (intptr_t) Universe::verify_oop_bits());
391 
392   // Compare tmp1 and tmp2.  We don't use a compare
393   // instruction here because the flags register is live.
394   __ eor(tmp1, tmp1, tmp2);
395   __ cbnz(tmp1, error);
396 
397   // make sure klass is 'reasonable', which is not zero.
398   __ load_klass(obj, obj); // get klass
399   __ cbz(obj, error);      // if klass is null it is broken
400 }
401 
402 #ifdef COMPILER2
403 
404 OptoReg::Name BarrierSetAssembler::encode_float_vector_register_size(const Node* node, OptoReg::Name opto_reg) {
405   switch (node->ideal_reg()) {
406     case Op_RegF:
407       // No need to refine. The original encoding is already fine to distinguish.
408       assert(opto_reg % 4 == 0, "Float register should only occupy a single slot");
409       break;
410     // Use different encoding values of the same fp/vector register to help distinguish different sizes.
411     // Such as V16. The OptoReg::name and its corresponding slot value are
412     // "V16": 64, "V16_H": 65, "V16_J": 66, "V16_K": 67.
413     case Op_RegD:
414     case Op_VecD:
415       opto_reg &= ~3;
416       opto_reg |= 1;
417       break;
418     case Op_VecX:
419       opto_reg &= ~3;
420       opto_reg |= 2;
421       break;
422     case Op_VecA:
423       opto_reg &= ~3;
424       opto_reg |= 3;
425       break;
426     default:
427       assert(false, "unexpected ideal register");
428       ShouldNotReachHere();
429   }
430   return opto_reg;
431 }
432 
433 OptoReg::Name BarrierSetAssembler::refine_register(const Node* node, OptoReg::Name opto_reg) {
434   if (!OptoReg::is_reg(opto_reg)) {
435     return OptoReg::Bad;
436   }
437 
438   const VMReg vm_reg = OptoReg::as_VMReg(opto_reg);
439   if (vm_reg->is_FloatRegister()) {
440     opto_reg = encode_float_vector_register_size(node, opto_reg);
441   }
442 
443   return opto_reg;
444 }
445 
446 #undef __
447 #define __ _masm->
448 
449 void SaveLiveRegisters::initialize(BarrierStubC2* stub) {
450   int index = -1;
451   GrowableArray<RegisterData> registers;
452   VMReg prev_vm_reg = VMRegImpl::Bad();
453 
454   RegMaskIterator rmi(stub->preserve_set());
455   while (rmi.has_next()) {
456     OptoReg::Name opto_reg = rmi.next();
457     VMReg vm_reg = OptoReg::as_VMReg(opto_reg);
458 
459     if (vm_reg->is_Register()) {
460       // GPR may have one or two slots in regmask
461       // Determine whether the current vm_reg is the same physical register as the previous one
462       if (is_same_register(vm_reg, prev_vm_reg)) {
463         registers.at(index)._slots++;
464       } else {
465         RegisterData reg_data = { vm_reg, 1 };
466         index = registers.append(reg_data);
467       }
468     } else if (vm_reg->is_FloatRegister()) {
469       // We have size encoding in OptoReg of stub->preserve_set()
470       // After encoding, float/neon/sve register has only one slot in regmask
471       // Decode it to get the actual size
472       VMReg vm_reg_base = vm_reg->as_FloatRegister()->as_VMReg();
473       int slots = decode_float_vector_register_size(opto_reg);
474       RegisterData reg_data = { vm_reg_base, slots };
475       index = registers.append(reg_data);
476     } else if (vm_reg->is_PRegister()) {
477       // PRegister has only one slot in regmask
478       RegisterData reg_data = { vm_reg, 1 };
479       index = registers.append(reg_data);
480     } else {
481       assert(false, "Unknown register type");
482       ShouldNotReachHere();
483     }
484     prev_vm_reg = vm_reg;
485   }
486 
487   // Record registers that needs to be saved/restored
488   for (GrowableArrayIterator<RegisterData> it = registers.begin(); it != registers.end(); ++it) {
489     RegisterData reg_data = *it;
490     VMReg vm_reg = reg_data._reg;
491     int slots = reg_data._slots;
492     if (vm_reg->is_Register()) {
493       assert(slots == 1 || slots == 2, "Unexpected register save size");
494       _gp_regs += RegSet::of(vm_reg->as_Register());
495     } else if (vm_reg->is_FloatRegister()) {
496       if (slots == 1 || slots == 2) {
497         _fp_regs += FloatRegSet::of(vm_reg->as_FloatRegister());
498       } else if (slots == 4) {
499         _neon_regs += FloatRegSet::of(vm_reg->as_FloatRegister());
500       } else {
501         assert(slots == Matcher::scalable_vector_reg_size(T_FLOAT), "Unexpected register save size");
502         _sve_regs += FloatRegSet::of(vm_reg->as_FloatRegister());
503       }
504     } else {
505       assert(vm_reg->is_PRegister() && slots == 1, "Unknown register type");
506       _p_regs += PRegSet::of(vm_reg->as_PRegister());
507     }
508   }
509 
510   // Remove C-ABI SOE registers and scratch regs
511   _gp_regs -= RegSet::range(r19, r30) + RegSet::of(r8, r9);
512 
513   // Remove C-ABI SOE fp registers
514   _fp_regs -= FloatRegSet::range(v8, v15);
515 }
516 
517 enum RC SaveLiveRegisters::rc_class(VMReg reg) {
518   if (reg->is_reg()) {
519     if (reg->is_Register()) {
520       return rc_int;
521     } else if (reg->is_FloatRegister()) {
522       return rc_float;
523     } else if (reg->is_PRegister()) {
524       return rc_predicate;
525     }
526   }
527   if (reg->is_stack()) {
528     return rc_stack;
529   }
530   return rc_bad;
531 }
532 
533 bool SaveLiveRegisters::is_same_register(VMReg reg1, VMReg reg2) {
534   if (reg1 == reg2) {
535     return true;
536   }
537   if (rc_class(reg1) == rc_class(reg2)) {
538     if (reg1->is_Register()) {
539       return reg1->as_Register() == reg2->as_Register();
540     } else if (reg1->is_FloatRegister()) {
541       return reg1->as_FloatRegister() == reg2->as_FloatRegister();
542     } else if (reg1->is_PRegister()) {
543       return reg1->as_PRegister() == reg2->as_PRegister();
544     }
545   }
546   return false;
547 }
548 
549 int SaveLiveRegisters::decode_float_vector_register_size(OptoReg::Name opto_reg) {
550   switch (opto_reg & 3) {
551     case 0:
552       return 1;
553     case 1:
554       return 2;
555     case 2:
556       return 4;
557     case 3:
558       return Matcher::scalable_vector_reg_size(T_FLOAT);
559     default:
560       ShouldNotReachHere();
561       return 0;
562   }
563 }
564 
565 SaveLiveRegisters::SaveLiveRegisters(MacroAssembler* masm, BarrierStubC2* stub)
566   : _masm(masm),
567     _gp_regs(),
568     _fp_regs(),
569     _neon_regs(),
570     _sve_regs(),
571     _p_regs() {
572 
573   // Figure out what registers to save/restore
574   initialize(stub);
575 
576   // Save registers
577   __ push(_gp_regs, sp);
578   __ push_fp(_fp_regs, sp, MacroAssembler::PushPopFp);
579   __ push_fp(_neon_regs, sp, MacroAssembler::PushPopNeon);
580   __ push_fp(_sve_regs, sp, MacroAssembler::PushPopSVE);
581   __ push_p(_p_regs, sp);
582 }
583 
584 SaveLiveRegisters::~SaveLiveRegisters() {
585   // Restore registers
586   __ pop_p(_p_regs, sp);
587   __ pop_fp(_sve_regs, sp, MacroAssembler::PushPopSVE);
588   __ pop_fp(_neon_regs, sp, MacroAssembler::PushPopNeon);
589   __ pop_fp(_fp_regs, sp, MacroAssembler::PushPopFp);
590 
591   // External runtime call may clobber ptrue reg
592   __ reinitialize_ptrue();
593 
594   __ pop(_gp_regs, sp);
595 }
596 
597 #endif // COMPILER2