1 /* 2 * Copyright (c) 2018, 2022, 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 #ifndef CPU_AARCH64_GC_SHARED_BARRIERSETASSEMBLER_AARCH64_HPP 26 #define CPU_AARCH64_GC_SHARED_BARRIERSETASSEMBLER_AARCH64_HPP 27 28 #include "asm/macroAssembler.hpp" 29 #include "gc/shared/barrierSet.hpp" 30 #include "gc/shared/barrierSetNMethod.hpp" 31 #include "memory/allocation.hpp" 32 #include "oops/access.hpp" 33 #ifdef COMPILER2 34 #include "opto/optoreg.hpp" 35 36 class BarrierStubC2; 37 class Node; 38 #endif // COMPILER2 39 40 enum class NMethodPatchingType { 41 stw_instruction_and_data_patch, 42 conc_instruction_and_data_patch, 43 conc_data_patch 44 }; 45 46 class BarrierSetAssembler: public CHeapObj<mtGC> { 47 public: 48 virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, 49 Register src, Register dst, Register count, RegSet saved_regs) {} 50 virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, 51 Register start, Register count, Register tmp, RegSet saved_regs) {} 52 53 virtual void copy_load_at(MacroAssembler* masm, 54 DecoratorSet decorators, 55 BasicType type, 56 size_t bytes, 57 Register dst1, 58 Register dst2, 59 Address src, 60 Register tmp); 61 62 virtual void copy_store_at(MacroAssembler* masm, 63 DecoratorSet decorators, 64 BasicType type, 65 size_t bytes, 66 Address dst, 67 Register src1, 68 Register src2, 69 Register tmp1, 70 Register tmp2, 71 Register tmp3); 72 73 virtual void copy_load_at(MacroAssembler* masm, 74 DecoratorSet decorators, 75 BasicType type, 76 size_t bytes, 77 FloatRegister dst1, 78 FloatRegister dst2, 79 Address src, 80 Register tmp1, 81 Register tmp2, 82 FloatRegister vec_tmp); 83 84 virtual void copy_store_at(MacroAssembler* masm, 85 DecoratorSet decorators, 86 BasicType type, 87 size_t bytes, 88 Address dst, 89 FloatRegister src1, 90 FloatRegister src2, 91 Register tmp1, 92 Register tmp2, 93 Register tmp3, 94 FloatRegister vec_tmp1, 95 FloatRegister vec_tmp2, 96 FloatRegister vec_tmp3); 97 98 virtual void load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, 99 Register dst, Address src, Register tmp1, Register tmp2); 100 virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, 101 Address dst, Register val, Register tmp1, Register tmp2, Register tmp3); 102 103 virtual void value_copy(MacroAssembler* masm, DecoratorSet decorators, 104 Register src, Register dst, Register value_klass); 105 virtual void flat_field_copy(MacroAssembler* masm, DecoratorSet decorators, 106 Register src, Register dst, Register inline_layout_info); 107 108 virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env, 109 Register obj, Register tmp, Label& slowpath); 110 111 virtual void tlab_allocate(MacroAssembler* masm, 112 Register obj, // result: pointer to object after successful allocation 113 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise 114 int con_size_in_bytes, // object size in bytes if known at compile time 115 Register t1, // temp register 116 Register t2, // temp register 117 Label& slow_case // continuation point if fast allocation fails 118 ); 119 120 virtual void barrier_stubs_init() {} 121 122 virtual NMethodPatchingType nmethod_patching_type() { return NMethodPatchingType::stw_instruction_and_data_patch; } 123 124 virtual void nmethod_entry_barrier(MacroAssembler* masm, Label* slow_path, Label* continuation, Label* guard); 125 virtual void c2i_entry_barrier(MacroAssembler* masm); 126 127 virtual void check_oop(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2, Label& error); 128 129 virtual bool supports_instruction_patching() { 130 NMethodPatchingType patching_type = nmethod_patching_type(); 131 return patching_type == NMethodPatchingType::conc_instruction_and_data_patch || 132 patching_type == NMethodPatchingType::stw_instruction_and_data_patch; 133 } 134 135 static address patching_epoch_addr(); 136 static void clear_patching_epoch(); 137 static void increment_patching_epoch(); 138 139 #ifdef COMPILER2 140 OptoReg::Name encode_float_vector_register_size(const Node* node, 141 OptoReg::Name opto_reg); 142 OptoReg::Name refine_register(const Node* node, 143 OptoReg::Name opto_reg); 144 #endif // COMPILER2 145 }; 146 147 #ifdef COMPILER2 148 149 // This class saves and restores the registers that need to be preserved across 150 // the runtime call represented by a given C2 barrier stub. Use as follows: 151 // { 152 // SaveLiveRegisters save(masm, stub); 153 // .. 154 // __ blr(...); 155 // .. 156 // } 157 class SaveLiveRegisters { 158 private: 159 struct RegisterData { 160 VMReg _reg; 161 int _slots; // slots occupied once pushed into stack 162 163 // Used by GrowableArray::find() 164 bool operator == (const RegisterData& other) { 165 return _reg == other._reg; 166 } 167 }; 168 169 MacroAssembler* const _masm; 170 RegSet _gp_regs; 171 FloatRegSet _fp_regs; 172 FloatRegSet _neon_regs; 173 FloatRegSet _sve_regs; 174 PRegSet _p_regs; 175 176 static enum RC rc_class(VMReg reg); 177 static bool is_same_register(VMReg reg1, VMReg reg2); 178 static int decode_float_vector_register_size(OptoReg::Name opto_reg); 179 180 public: 181 void initialize(BarrierStubC2* stub); 182 SaveLiveRegisters(MacroAssembler* masm, BarrierStubC2* stub); 183 ~SaveLiveRegisters(); 184 }; 185 186 #endif // COMPILER2 187 188 #endif // CPU_AARCH64_GC_SHARED_BARRIERSETASSEMBLER_AARCH64_HPP