1 /* 2 * Copyright (c) 2016, 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 #ifndef SHARE_OPTO_ARRAYCOPYNODE_HPP 26 #define SHARE_OPTO_ARRAYCOPYNODE_HPP 27 28 #include "gc/shared/c2/barrierSetC2.hpp" 29 #include "opto/callnode.hpp" 30 31 class GraphKit; 32 33 class ArrayCopyNode : public CallNode { 34 static const TypeFunc* _arraycopy_type_Type; 35 private: 36 37 // What kind of arraycopy variant is this? 38 enum { 39 None, // not set yet 40 ArrayCopy, // System.arraycopy() 41 CloneInst, // A clone of instances 42 CloneArray, // A clone of arrays that don't require a barrier 43 // - depends on GC - some need to treat oop arrays separately 44 CloneOopArray, // An oop array clone that requires GC barriers 45 CopyOf, // Arrays.copyOf() 46 CopyOfRange // Arrays.copyOfRange() 47 } _kind; 48 49 #ifndef PRODUCT 50 static const char* _kind_names[CopyOfRange+1]; 51 #endif 52 // Is the alloc obtained with 53 // AllocateArrayNode::Ideal_array_allocation() tightly coupled 54 // (arraycopy follows immediately the allocation)? 55 // We cache the result of LibraryCallKit::tightly_coupled_allocation 56 // here because it's much easier to find whether there's a tightly 57 // couple allocation at parse time than at macro expansion time. At 58 // macro expansion time, for every use of the allocation node we 59 // would need to figure out whether it happens after the arraycopy (and 60 // can be ignored) or between the allocation and the arraycopy. At 61 // parse time, it's straightforward because whatever happens after 62 // the arraycopy is not parsed yet so doesn't exist when 63 // LibraryCallKit::tightly_coupled_allocation() is called. 64 bool _alloc_tightly_coupled; 65 bool _has_negative_length_guard; 66 67 bool _arguments_validated; 68 69 public: 70 71 static const TypeFunc* arraycopy_type() { 72 assert(_arraycopy_type_Type != nullptr, "should be initialized"); 73 return _arraycopy_type_Type; 74 } 75 76 static void initialize_arraycopy_Type() { 77 assert(_arraycopy_type_Type == nullptr, "should be"); 78 const Type** fields = TypeTuple::fields(ParmLimit - TypeFunc::Parms); 79 fields[Src] = TypeInstPtr::BOTTOM; 80 fields[SrcPos] = TypeInt::INT; 81 fields[Dest] = TypeInstPtr::BOTTOM; 82 fields[DestPos] = TypeInt::INT; 83 fields[Length] = TypeInt::INT; 84 fields[SrcLen] = TypeInt::INT; 85 fields[DestLen] = TypeInt::INT; 86 fields[SrcKlass] = TypeKlassPtr::BOTTOM; 87 fields[DestKlass] = TypeKlassPtr::BOTTOM; 88 const TypeTuple *domain = TypeTuple::make(ParmLimit, fields); 89 90 // create result type (range) 91 fields = TypeTuple::fields(0); 92 93 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields); 94 95 _arraycopy_type_Type = TypeFunc::make(domain, range); 96 } 97 98 private: 99 ArrayCopyNode(Compile* C, bool alloc_tightly_coupled, bool has_negative_length_guard); 100 101 intptr_t get_length_if_constant(PhaseGVN *phase) const; 102 int get_count(PhaseGVN *phase) const; 103 static const TypePtr* get_address_type(PhaseGVN* phase, const TypePtr* atp, Node* n); 104 105 Node* try_clone_instance(PhaseGVN *phase, bool can_reshape, int count); 106 bool prepare_array_copy(PhaseGVN *phase, bool can_reshape, 107 Node*& adr_src, Node*& base_src, Node*& adr_dest, Node*& base_dest, 108 BasicType& copy_type, const Type*& value_type, bool& disjoint_bases); 109 void array_copy_test_overlap(PhaseGVN *phase, bool can_reshape, 110 bool disjoint_bases, int count, 111 Node*& forward_ctl, Node*& backward_ctl); 112 Node* array_copy_forward(PhaseGVN *phase, bool can_reshape, Node*& ctl, 113 Node* mem, 114 const TypePtr* atp_src, const TypePtr* atp_dest, 115 Node* adr_src, Node* base_src, Node* adr_dest, Node* base_dest, 116 BasicType copy_type, const Type* value_type, int count); 117 Node* array_copy_backward(PhaseGVN *phase, bool can_reshape, Node*& ctl, 118 Node* mem, 119 const TypePtr* atp_src, const TypePtr* atp_dest, 120 Node* adr_src, Node* base_src, Node* adr_dest, Node* base_dest, 121 BasicType copy_type, const Type* value_type, int count); 122 bool finish_transform(PhaseGVN *phase, bool can_reshape, 123 Node* ctl, Node *mem); 124 static bool may_modify_helper(const TypeOopPtr* t_oop, Node* n, PhaseValues* phase, CallNode*& call); 125 public: 126 static Node* load(BarrierSetC2* bs, PhaseGVN *phase, Node*& ctl, MergeMemNode* mem, Node* addr, const TypePtr* adr_type, const Type *type, BasicType bt); 127 private: 128 void store(BarrierSetC2* bs, PhaseGVN *phase, Node*& ctl, MergeMemNode* mem, Node* addr, const TypePtr* adr_type, Node* val, const Type *type, BasicType bt); 129 130 public: 131 132 enum { 133 Src = TypeFunc::Parms, 134 SrcPos, 135 Dest, 136 DestPos, 137 Length, 138 SrcLen, 139 DestLen, 140 SrcKlass, 141 DestKlass, 142 ParmLimit 143 }; 144 145 // Results from escape analysis for non escaping inputs 146 const TypeOopPtr* _src_type; 147 const TypeOopPtr* _dest_type; 148 149 static ArrayCopyNode* make(GraphKit* kit, bool may_throw, 150 Node* src, Node* src_offset, 151 Node* dest, Node* dest_offset, 152 Node* length, 153 bool alloc_tightly_coupled, 154 bool has_negative_length_guard, 155 Node* src_klass = nullptr, Node* dest_klass = nullptr, 156 Node* src_length = nullptr, Node* dest_length = nullptr); 157 158 void connect_outputs(GraphKit* kit, bool deoptimize_on_exception = false); 159 160 bool is_arraycopy() const { assert(_kind != None, "should bet set"); return _kind == ArrayCopy; } 161 bool is_arraycopy_validated() const { assert(_kind != None, "should bet set"); return _kind == ArrayCopy && _arguments_validated; } 162 bool is_clone_inst() const { assert(_kind != None, "should bet set"); return _kind == CloneInst; } 163 // is_clone_array - true for all arrays when using GCs that has no barriers 164 bool is_clone_array() const { assert(_kind != None, "should bet set"); return _kind == CloneArray; } 165 // is_clone_oop_array is used when oop arrays need GC barriers 166 bool is_clone_oop_array() const { assert(_kind != None, "should bet set"); return _kind == CloneOopArray; } 167 // is_clonebasic - is true for any type of clone that doesn't need a writebarrier. 168 bool is_clonebasic() const { assert(_kind != None, "should bet set"); return _kind == CloneInst || _kind == CloneArray; } 169 bool is_copyof() const { assert(_kind != None, "should bet set"); return _kind == CopyOf; } 170 bool is_copyof_validated() const { assert(_kind != None, "should bet set"); return _kind == CopyOf && _arguments_validated; } 171 bool is_copyofrange() const { assert(_kind != None, "should bet set"); return _kind == CopyOfRange; } 172 bool is_copyofrange_validated() const { assert(_kind != None, "should bet set"); return _kind == CopyOfRange && _arguments_validated; } 173 174 void set_arraycopy(bool validated) { assert(_kind == None, "shouldn't bet set yet"); _kind = ArrayCopy; _arguments_validated = validated; } 175 void set_clone_inst() { assert(_kind == None, "shouldn't bet set yet"); _kind = CloneInst; } 176 void set_clone_array() { assert(_kind == None, "shouldn't bet set yet"); _kind = CloneArray; } 177 void set_clone_oop_array() { assert(_kind == None, "shouldn't bet set yet"); _kind = CloneOopArray; } 178 void set_copyof(bool validated) { assert(_kind == None, "shouldn't bet set yet"); _kind = CopyOf; _arguments_validated = validated; } 179 void set_copyofrange(bool validated) { assert(_kind == None, "shouldn't bet set yet"); _kind = CopyOfRange; _arguments_validated = validated; } 180 181 virtual int Opcode() const; 182 virtual uint size_of() const; // Size is bigger 183 virtual bool guaranteed_safepoint() { return false; } 184 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 185 186 virtual bool may_modify(const TypeOopPtr* t_oop, PhaseValues* phase); 187 188 bool is_alloc_tightly_coupled() const { return _alloc_tightly_coupled; } 189 190 bool has_negative_length_guard() const { return _has_negative_length_guard; } 191 192 static bool may_modify(const TypeOopPtr* t_oop, MemBarNode* mb, PhaseValues* phase, ArrayCopyNode*& ac); 193 194 static int get_partial_inline_vector_lane_count(BasicType type, int const_len); 195 196 bool modifies(intptr_t offset_lo, intptr_t offset_hi, PhaseValues* phase, bool must_modify) const; 197 198 #ifndef PRODUCT 199 virtual void dump_spec(outputStream *st) const; 200 virtual void dump_compact_spec(outputStream* st) const; 201 #endif 202 }; 203 #endif // SHARE_OPTO_ARRAYCOPYNODE_HPP