1 /* 2 * Copyright (c) 2015, 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_VM_OPTO_ARRAYCOPYNODE_HPP 26 #define SHARE_VM_OPTO_ARRAYCOPYNODE_HPP 27 28 #include "opto/callnode.hpp" 29 30 class GraphKit; 31 32 class ArrayCopyNode : public CallNode { 33 private: 34 35 // What kind of arraycopy variant is this? 36 enum { 37 None, // not set yet 38 ArrayCopy, // System.arraycopy() 39 CloneBasic, // A clone that can be copied by 64 bit chunks 40 CloneOop, // An oop array clone 41 CopyOf, // Arrays.copyOf() 42 CopyOfRange // Arrays.copyOfRange() 43 } _kind; 44 45 #ifndef PRODUCT 46 static const char* _kind_names[CopyOfRange+1]; 47 #endif 48 // Is the alloc obtained with 49 // AllocateArrayNode::Ideal_array_allocation() tighly coupled 50 // (arraycopy follows immediately the allocation)? 51 // We cache the result of LibraryCallKit::tightly_coupled_allocation 52 // here because it's much easier to find whether there's a tightly 53 // couple allocation at parse time than at macro expansion time. At 54 // macro expansion time, for every use of the allocation node we 55 // would need to figure out whether it happens after the arraycopy (and 56 // can be ignored) or between the allocation and the arraycopy. At 57 // parse time, it's straightforward because whatever happens after 58 // the arraycopy is not parsed yet so doesn't exist when 59 // LibraryCallKit::tightly_coupled_allocation() is called. 60 bool _alloc_tightly_coupled; 61 62 bool _arguments_validated; 63 64 static const TypeFunc* arraycopy_type() { 65 const Type** fields = TypeTuple::fields(ParmLimit - TypeFunc::Parms); 66 fields[Src] = TypeInstPtr::BOTTOM; 67 fields[SrcPos] = TypeInt::INT; 68 fields[Dest] = TypeInstPtr::BOTTOM; 69 fields[DestPos] = TypeInt::INT; 70 fields[Length] = TypeInt::INT; 71 fields[SrcLen] = TypeInt::INT; 72 fields[DestLen] = TypeInt::INT; 73 fields[SrcKlass] = TypeKlassPtr::BOTTOM; 74 fields[DestKlass] = TypeKlassPtr::BOTTOM; 75 const TypeTuple *domain = TypeTuple::make(ParmLimit, fields); 76 77 // create result type (range) 78 fields = TypeTuple::fields(0); 79 80 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields); 81 82 return TypeFunc::make(domain, domain, range); 83 } 84 85 ArrayCopyNode(Compile* C, bool alloc_tightly_coupled); 86 87 intptr_t get_length_if_constant(PhaseGVN *phase) const; 88 int get_count(PhaseGVN *phase) const; 89 static const TypePtr* get_address_type(PhaseGVN *phase, Node* n); 90 91 Node* try_clone_instance(PhaseGVN *phase, bool can_reshape, int count); 92 bool prepare_array_copy(PhaseGVN *phase, bool can_reshape, 93 Node*& adr_src, Node*& base_src, Node*& adr_dest, Node*& base_dest, 94 BasicType& copy_type, const Type*& value_type, bool& disjoint_bases); 95 void array_copy_test_overlap(PhaseGVN *phase, bool can_reshape, 96 bool disjoint_bases, int count, 97 Node*& forward_ctl, Node*& backward_ctl); 98 Node* array_copy_forward(PhaseGVN *phase, bool can_reshape, Node* ctl, 99 Node* start_mem_src, Node* start_mem_dest, 100 const TypePtr* atp_src, const TypePtr* atp_dest, 101 Node* adr_src, Node* base_src, Node* adr_dest, Node* base_dest, 102 BasicType copy_type, const Type* value_type, int count); 103 Node* array_copy_backward(PhaseGVN *phase, bool can_reshape, Node* ctl, 104 Node *start_mem_src, Node* start_mem_dest, 105 const TypePtr* atp_src, const TypePtr* atp_dest, 106 Node* adr_src, Node* base_src, Node* adr_dest, Node* base_dest, 107 BasicType copy_type, const Type* value_type, int count); 108 bool finish_transform(PhaseGVN *phase, bool can_reshape, 109 Node* ctl, Node *mem); 110 static bool may_modify_helper(const TypeOopPtr *t_oop, Node* n, PhaseTransform *phase); 111 112 public: 113 114 enum { 115 Src = TypeFunc::Parms, 116 SrcPos, 117 Dest, 118 DestPos, 119 Length, 120 SrcLen, 121 DestLen, 122 SrcKlass, 123 DestKlass, 124 ParmLimit 125 }; 126 127 // Results from escape analysis for non escaping inputs 128 const TypeOopPtr* _src_type; 129 const TypeOopPtr* _dest_type; 130 131 static ArrayCopyNode* make(GraphKit* kit, bool may_throw, 132 Node* src, Node* src_offset, 133 Node* dest, Node* dest_offset, 134 Node* length, 135 bool alloc_tightly_coupled, 136 Node* src_klass = NULL, Node* dest_klass = NULL, 137 Node* src_length = NULL, Node* dest_length = NULL); 138 139 void connect_outputs(GraphKit* kit); 140 141 bool is_arraycopy() const { assert(_kind != None, "should bet set"); return _kind == ArrayCopy; } 142 bool is_arraycopy_validated() const { assert(_kind != None, "should bet set"); return _kind == ArrayCopy && _arguments_validated; } 143 bool is_clonebasic() const { assert(_kind != None, "should bet set"); return _kind == CloneBasic; } 144 bool is_cloneoop() const { assert(_kind != None, "should bet set"); return _kind == CloneOop; } 145 bool is_copyof() const { assert(_kind != None, "should bet set"); return _kind == CopyOf; } 146 bool is_copyof_validated() const { assert(_kind != None, "should bet set"); return _kind == CopyOf && _arguments_validated; } 147 bool is_copyofrange() const { assert(_kind != None, "should bet set"); return _kind == CopyOfRange; } 148 bool is_copyofrange_validated() const { assert(_kind != None, "should bet set"); return _kind == CopyOfRange && _arguments_validated; } 149 150 void set_arraycopy(bool validated) { assert(_kind == None, "shouldn't bet set yet"); _kind = ArrayCopy; _arguments_validated = validated; } 151 void set_clonebasic() { assert(_kind == None, "shouldn't bet set yet"); _kind = CloneBasic; } 152 void set_cloneoop() { assert(_kind == None, "shouldn't bet set yet"); _kind = CloneOop; } 153 void set_copyof(bool validated) { assert(_kind == None, "shouldn't bet set yet"); _kind = CopyOf; _arguments_validated = validated; } 154 void set_copyofrange(bool validated) { assert(_kind == None, "shouldn't bet set yet"); _kind = CopyOfRange; _arguments_validated = validated; } 155 156 virtual int Opcode() const; 157 virtual uint size_of() const; // Size is bigger 158 virtual bool guaranteed_safepoint() { return false; } 159 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 160 161 virtual bool may_modify(const TypeOopPtr *t_oop, PhaseTransform *phase); 162 163 bool is_alloc_tightly_coupled() const { return _alloc_tightly_coupled; } 164 165 static bool may_modify(const TypeOopPtr *t_oop, MemBarNode* mb, PhaseTransform *phase); 166 bool modifies(intptr_t offset_lo, intptr_t offset_hi, PhaseTransform* phase, bool must_modify); 167 168 #ifndef PRODUCT 169 virtual void dump_spec(outputStream *st) const; 170 virtual void dump_compact_spec(outputStream* st) const; 171 #endif 172 }; 173 #endif // SHARE_VM_OPTO_ARRAYCOPYNODE_HPP