1.1 --- a/src/share/vm/opto/library_call.cpp Wed Jul 01 15:06:54 2009 -0700 1.2 +++ b/src/share/vm/opto/library_call.cpp Wed Jul 01 20:22:18 2009 -0700 1.3 @@ -165,6 +165,7 @@ 1.4 bool inline_native_getLength(); 1.5 bool inline_array_copyOf(bool is_copyOfRange); 1.6 bool inline_array_equals(); 1.7 + void copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, bool is_array, bool card_mark); 1.8 bool inline_native_clone(bool is_virtual); 1.9 bool inline_native_Reflection_getCallerClass(); 1.10 bool inline_native_AtomicLong_get(); 1.11 @@ -181,7 +182,6 @@ 1.12 Node* src, Node* src_offset, 1.13 Node* dest, Node* dest_offset, 1.14 Node* copy_length, 1.15 - int nargs, // arguments on stack for debug info 1.16 bool disjoint_bases = false, 1.17 bool length_never_negative = false, 1.18 RegionNode* slow_region = NULL); 1.19 @@ -202,17 +202,16 @@ 1.20 void generate_slow_arraycopy(const TypePtr* adr_type, 1.21 Node* src, Node* src_offset, 1.22 Node* dest, Node* dest_offset, 1.23 - Node* copy_length, 1.24 - int nargs); 1.25 + Node* copy_length); 1.26 Node* generate_checkcast_arraycopy(const TypePtr* adr_type, 1.27 Node* dest_elem_klass, 1.28 Node* src, Node* src_offset, 1.29 Node* dest, Node* dest_offset, 1.30 - Node* copy_length, int nargs); 1.31 + Node* copy_length); 1.32 Node* generate_generic_arraycopy(const TypePtr* adr_type, 1.33 Node* src, Node* src_offset, 1.34 Node* dest, Node* dest_offset, 1.35 - Node* copy_length, int nargs); 1.36 + Node* copy_length); 1.37 void generate_unchecked_arraycopy(const TypePtr* adr_type, 1.38 BasicType basic_elem_type, 1.39 bool disjoint_bases, 1.40 @@ -3229,7 +3228,8 @@ 1.41 Node* orig_tail = _gvn.transform( new(C, 3) SubINode(orig_length, start) ); 1.42 Node* moved = generate_min_max(vmIntrinsics::_min, orig_tail, length); 1.43 1.44 - Node* newcopy = new_array(klass_node, length, nargs); 1.45 + const bool raw_mem_only = true; 1.46 + Node* newcopy = new_array(klass_node, length, nargs, raw_mem_only); 1.47 1.48 // Generate a direct call to the right arraycopy function(s). 1.49 // We know the copy is disjoint but we might not know if the 1.50 @@ -3240,7 +3240,7 @@ 1.51 bool length_never_negative = true; 1.52 generate_arraycopy(TypeAryPtr::OOPS, T_OBJECT, 1.53 original, start, newcopy, intcon(0), moved, 1.54 - nargs, disjoint_bases, length_never_negative); 1.55 + disjoint_bases, length_never_negative); 1.56 1.57 push(newcopy); 1.58 } 1.59 @@ -3882,6 +3882,98 @@ 1.60 return true; 1.61 } 1.62 1.63 +//------------------------clone_coping----------------------------------- 1.64 +// Helper function for inline_native_clone. 1.65 +void LibraryCallKit::copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, bool is_array, bool card_mark) { 1.66 + assert(obj_size != NULL, ""); 1.67 + Node* raw_obj = alloc_obj->in(1); 1.68 + assert(alloc_obj->is_CheckCastPP() && raw_obj->is_Proj() && raw_obj->in(0)->is_Allocate(), ""); 1.69 + 1.70 + if (ReduceBulkZeroing) { 1.71 + // We will be completely responsible for initializing this object - 1.72 + // mark Initialize node as complete. 1.73 + AllocateNode* alloc = AllocateNode::Ideal_allocation(alloc_obj, &_gvn); 1.74 + // The object was just allocated - there should be no any stores! 1.75 + guarantee(alloc != NULL && alloc->maybe_set_complete(&_gvn), ""); 1.76 + } 1.77 + 1.78 + // Cast to Object for arraycopy. 1.79 + // We can't use the original CheckCastPP since it should be moved 1.80 + // after the arraycopy to prevent stores flowing above it. 1.81 + Node* new_obj = new(C, 2) CheckCastPPNode(alloc_obj->in(0), raw_obj, 1.82 + TypeInstPtr::NOTNULL); 1.83 + new_obj = _gvn.transform(new_obj); 1.84 + // Substitute in the locally valid dest_oop. 1.85 + replace_in_map(alloc_obj, new_obj); 1.86 + 1.87 + // Copy the fastest available way. 1.88 + // TODO: generate fields copies for small objects instead. 1.89 + Node* src = obj; 1.90 + Node* dest = new_obj; 1.91 + Node* size = _gvn.transform(obj_size); 1.92 + 1.93 + // Exclude the header but include array length to copy by 8 bytes words. 1.94 + // Can't use base_offset_in_bytes(bt) since basic type is unknown. 1.95 + int base_off = is_array ? arrayOopDesc::length_offset_in_bytes() : 1.96 + instanceOopDesc::base_offset_in_bytes(); 1.97 + // base_off: 1.98 + // 8 - 32-bit VM 1.99 + // 12 - 64-bit VM, compressed oops 1.100 + // 16 - 64-bit VM, normal oops 1.101 + if (base_off % BytesPerLong != 0) { 1.102 + assert(UseCompressedOops, ""); 1.103 + if (is_array) { 1.104 + // Exclude length to copy by 8 bytes words. 1.105 + base_off += sizeof(int); 1.106 + } else { 1.107 + // Include klass to copy by 8 bytes words. 1.108 + base_off = instanceOopDesc::klass_offset_in_bytes(); 1.109 + } 1.110 + assert(base_off % BytesPerLong == 0, "expect 8 bytes alignment"); 1.111 + } 1.112 + src = basic_plus_adr(src, base_off); 1.113 + dest = basic_plus_adr(dest, base_off); 1.114 + 1.115 + // Compute the length also, if needed: 1.116 + Node* countx = size; 1.117 + countx = _gvn.transform( new (C, 3) SubXNode(countx, MakeConX(base_off)) ); 1.118 + countx = _gvn.transform( new (C, 3) URShiftXNode(countx, intcon(LogBytesPerLong) )); 1.119 + 1.120 + const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; 1.121 + bool disjoint_bases = true; 1.122 + generate_unchecked_arraycopy(raw_adr_type, T_LONG, disjoint_bases, 1.123 + src, NULL, dest, NULL, countx); 1.124 + 1.125 + // If necessary, emit some card marks afterwards. (Non-arrays only.) 1.126 + if (card_mark) { 1.127 + assert(!is_array, ""); 1.128 + // Put in store barrier for any and all oops we are sticking 1.129 + // into this object. (We could avoid this if we could prove 1.130 + // that the object type contains no oop fields at all.) 1.131 + Node* no_particular_value = NULL; 1.132 + Node* no_particular_field = NULL; 1.133 + int raw_adr_idx = Compile::AliasIdxRaw; 1.134 + post_barrier(control(), 1.135 + memory(raw_adr_type), 1.136 + new_obj, 1.137 + no_particular_field, 1.138 + raw_adr_idx, 1.139 + no_particular_value, 1.140 + T_OBJECT, 1.141 + false); 1.142 + } 1.143 + 1.144 + // Move the original CheckCastPP after arraycopy. 1.145 + _gvn.hash_delete(alloc_obj); 1.146 + alloc_obj->set_req(0, control()); 1.147 + // Replace raw memory edge with new CheckCastPP to have a live oop 1.148 + // at safepoints instead of raw value. 1.149 + assert(new_obj->is_CheckCastPP() && new_obj->in(1) == alloc_obj->in(1), "sanity"); 1.150 + alloc_obj->set_req(1, new_obj); // cast to the original type 1.151 + _gvn.hash_find_insert(alloc_obj); // put back into GVN table 1.152 + // Restore in the locally valid dest_oop. 1.153 + replace_in_map(new_obj, alloc_obj); 1.154 +} 1.155 1.156 //------------------------inline_native_clone---------------------------- 1.157 // Here are the simple edge cases: 1.158 @@ -3916,8 +4008,9 @@ 1.159 // paths into result_reg: 1.160 enum { 1.161 _slow_path = 1, // out-of-line call to clone method (virtual or not) 1.162 - _objArray_path, // plain allocation, plus arrayof_oop_arraycopy 1.163 - _fast_path, // plain allocation, plus a CopyArray operation 1.164 + _objArray_path, // plain array allocation, plus arrayof_oop_arraycopy 1.165 + _array_path, // plain array allocation, plus arrayof_long_arraycopy 1.166 + _instance_path, // plain instance allocation, plus arrayof_long_arraycopy 1.167 PATH_LIMIT 1.168 }; 1.169 RegionNode* result_reg = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT); 1.170 @@ -3932,18 +4025,6 @@ 1.171 int raw_adr_idx = Compile::AliasIdxRaw; 1.172 const bool raw_mem_only = true; 1.173 1.174 - // paths into alloc_reg (on the fast path, just before the CopyArray): 1.175 - enum { _typeArray_alloc = 1, _instance_alloc, ALLOC_LIMIT }; 1.176 - RegionNode* alloc_reg = new(C, ALLOC_LIMIT) RegionNode(ALLOC_LIMIT); 1.177 - PhiNode* alloc_val = new(C, ALLOC_LIMIT) PhiNode(alloc_reg, raw_adr_type); 1.178 - PhiNode* alloc_siz = new(C, ALLOC_LIMIT) PhiNode(alloc_reg, TypeX_X); 1.179 - PhiNode* alloc_i_o = new(C, ALLOC_LIMIT) PhiNode(alloc_reg, Type::ABIO); 1.180 - PhiNode* alloc_mem = new(C, ALLOC_LIMIT) PhiNode(alloc_reg, Type::MEMORY, 1.181 - raw_adr_type); 1.182 - record_for_igvn(alloc_reg); 1.183 - 1.184 - bool card_mark = false; // (see below) 1.185 - 1.186 Node* array_ctl = generate_array_guard(obj_klass, (RegionNode*)NULL); 1.187 if (array_ctl != NULL) { 1.188 // It's an array. 1.189 @@ -3953,16 +4034,6 @@ 1.190 Node* obj_size = NULL; 1.191 Node* alloc_obj = new_array(obj_klass, obj_length, nargs, 1.192 raw_mem_only, &obj_size); 1.193 - assert(obj_size != NULL, ""); 1.194 - Node* raw_obj = alloc_obj->in(1); 1.195 - assert(raw_obj->is_Proj() && raw_obj->in(0)->is_Allocate(), ""); 1.196 - if (ReduceBulkZeroing) { 1.197 - AllocateNode* alloc = AllocateNode::Ideal_allocation(alloc_obj, &_gvn); 1.198 - if (alloc != NULL) { 1.199 - // We will be completely responsible for initializing this object. 1.200 - alloc->maybe_set_complete(&_gvn); 1.201 - } 1.202 - } 1.203 1.204 if (!use_ReduceInitialCardMarks()) { 1.205 // If it is an oop array, it requires very special treatment, 1.206 @@ -3976,7 +4047,7 @@ 1.207 bool length_never_negative = true; 1.208 generate_arraycopy(TypeAryPtr::OOPS, T_OBJECT, 1.209 obj, intcon(0), alloc_obj, intcon(0), 1.210 - obj_length, nargs, 1.211 + obj_length, 1.212 disjoint_bases, length_never_negative); 1.213 result_reg->init_req(_objArray_path, control()); 1.214 result_val->init_req(_objArray_path, alloc_obj); 1.215 @@ -3991,19 +4062,24 @@ 1.216 // the object. 1.217 1.218 // Otherwise, there are no card marks to worry about. 1.219 - alloc_val->init_req(_typeArray_alloc, raw_obj); 1.220 - alloc_siz->init_req(_typeArray_alloc, obj_size); 1.221 - alloc_reg->init_req(_typeArray_alloc, control()); 1.222 - alloc_i_o->init_req(_typeArray_alloc, i_o()); 1.223 - alloc_mem->init_req(_typeArray_alloc, memory(raw_adr_type)); 1.224 + 1.225 + if (!stopped()) { 1.226 + copy_to_clone(obj, alloc_obj, obj_size, true, false); 1.227 + 1.228 + // Present the results of the copy. 1.229 + result_reg->init_req(_array_path, control()); 1.230 + result_val->init_req(_array_path, alloc_obj); 1.231 + result_i_o ->set_req(_array_path, i_o()); 1.232 + result_mem ->set_req(_array_path, reset_memory()); 1.233 + } 1.234 } 1.235 1.236 - // We only go to the fast case code if we pass a number of guards. 1.237 + // We only go to the instance fast case code if we pass a number of guards. 1.238 // The paths which do not pass are accumulated in the slow_region. 1.239 RegionNode* slow_region = new (C, 1) RegionNode(1); 1.240 record_for_igvn(slow_region); 1.241 if (!stopped()) { 1.242 - // It's an instance. Make the slow-path tests. 1.243 + // It's an instance (we did array above). Make the slow-path tests. 1.244 // If this is a virtual call, we generate a funny guard. We grab 1.245 // the vtable entry corresponding to clone() from the target object. 1.246 // If the target method which we are calling happens to be the 1.247 @@ -4030,25 +4106,14 @@ 1.248 PreserveJVMState pjvms(this); 1.249 Node* obj_size = NULL; 1.250 Node* alloc_obj = new_instance(obj_klass, NULL, raw_mem_only, &obj_size); 1.251 - assert(obj_size != NULL, ""); 1.252 - Node* raw_obj = alloc_obj->in(1); 1.253 - assert(raw_obj->is_Proj() && raw_obj->in(0)->is_Allocate(), ""); 1.254 - if (ReduceBulkZeroing) { 1.255 - AllocateNode* alloc = AllocateNode::Ideal_allocation(alloc_obj, &_gvn); 1.256 - if (alloc != NULL && !alloc->maybe_set_complete(&_gvn)) 1.257 - alloc = NULL; 1.258 - } 1.259 - if (!use_ReduceInitialCardMarks()) { 1.260 - // Put in store barrier for any and all oops we are sticking 1.261 - // into this object. (We could avoid this if we could prove 1.262 - // that the object type contains no oop fields at all.) 1.263 - card_mark = true; 1.264 - } 1.265 - alloc_val->init_req(_instance_alloc, raw_obj); 1.266 - alloc_siz->init_req(_instance_alloc, obj_size); 1.267 - alloc_reg->init_req(_instance_alloc, control()); 1.268 - alloc_i_o->init_req(_instance_alloc, i_o()); 1.269 - alloc_mem->init_req(_instance_alloc, memory(raw_adr_type)); 1.270 + 1.271 + copy_to_clone(obj, alloc_obj, obj_size, false, !use_ReduceInitialCardMarks()); 1.272 + 1.273 + // Present the results of the slow call. 1.274 + result_reg->init_req(_instance_path, control()); 1.275 + result_val->init_req(_instance_path, alloc_obj); 1.276 + result_i_o ->set_req(_instance_path, i_o()); 1.277 + result_mem ->set_req(_instance_path, reset_memory()); 1.278 } 1.279 1.280 // Generate code for the slow case. We make a call to clone(). 1.281 @@ -4064,82 +4129,12 @@ 1.282 result_mem ->set_req(_slow_path, reset_memory()); 1.283 } 1.284 1.285 - // The object is allocated, as an array and/or an instance. Now copy it. 1.286 - set_control( _gvn.transform(alloc_reg) ); 1.287 - set_i_o( _gvn.transform(alloc_i_o) ); 1.288 - set_memory( _gvn.transform(alloc_mem), raw_adr_type ); 1.289 - Node* raw_obj = _gvn.transform(alloc_val); 1.290 - 1.291 - if (!stopped()) { 1.292 - // Copy the fastest available way. 1.293 - // (No need for PreserveJVMState, since we're using it all up now.) 1.294 - // TODO: generate fields/elements copies for small objects instead. 1.295 - Node* src = obj; 1.296 - Node* dest = raw_obj; 1.297 - Node* size = _gvn.transform(alloc_siz); 1.298 - 1.299 - // Exclude the header. 1.300 - int base_off = instanceOopDesc::base_offset_in_bytes(); 1.301 - if (UseCompressedOops) { 1.302 - assert(base_off % BytesPerLong != 0, "base with compressed oops"); 1.303 - // With compressed oops base_offset_in_bytes is 12 which creates 1.304 - // the gap since countx is rounded by 8 bytes below. 1.305 - // Copy klass and the gap. 1.306 - base_off = instanceOopDesc::klass_offset_in_bytes(); 1.307 - } 1.308 - src = basic_plus_adr(src, base_off); 1.309 - dest = basic_plus_adr(dest, base_off); 1.310 - 1.311 - // Compute the length also, if needed: 1.312 - Node* countx = size; 1.313 - countx = _gvn.transform( new (C, 3) SubXNode(countx, MakeConX(base_off)) ); 1.314 - countx = _gvn.transform( new (C, 3) URShiftXNode(countx, intcon(LogBytesPerLong) )); 1.315 - 1.316 - // Select an appropriate instruction to initialize the range. 1.317 - // The CopyArray instruction (if supported) can be optimized 1.318 - // into a discrete set of scalar loads and stores. 1.319 - bool disjoint_bases = true; 1.320 - generate_unchecked_arraycopy(raw_adr_type, T_LONG, disjoint_bases, 1.321 - src, NULL, dest, NULL, countx); 1.322 - 1.323 - // Now that the object is properly initialized, type it as an oop. 1.324 - // Use a secondary InitializeNode memory barrier. 1.325 - InitializeNode* init = insert_mem_bar_volatile(Op_Initialize, raw_adr_idx, 1.326 - raw_obj)->as_Initialize(); 1.327 - init->set_complete(&_gvn); // (there is no corresponding AllocateNode) 1.328 - Node* new_obj = new(C, 2) CheckCastPPNode(control(), raw_obj, 1.329 - TypeInstPtr::NOTNULL); 1.330 - new_obj = _gvn.transform(new_obj); 1.331 - 1.332 - // If necessary, emit some card marks afterwards. (Non-arrays only.) 1.333 - if (card_mark) { 1.334 - Node* no_particular_value = NULL; 1.335 - Node* no_particular_field = NULL; 1.336 - post_barrier(control(), 1.337 - memory(raw_adr_type), 1.338 - new_obj, 1.339 - no_particular_field, 1.340 - raw_adr_idx, 1.341 - no_particular_value, 1.342 - T_OBJECT, 1.343 - false); 1.344 - } 1.345 - // Present the results of the slow call. 1.346 - result_reg->init_req(_fast_path, control()); 1.347 - result_val->init_req(_fast_path, new_obj); 1.348 - result_i_o ->set_req(_fast_path, i_o()); 1.349 - result_mem ->set_req(_fast_path, reset_memory()); 1.350 - } 1.351 - 1.352 // Return the combined state. 1.353 set_control( _gvn.transform(result_reg) ); 1.354 set_i_o( _gvn.transform(result_i_o) ); 1.355 set_all_memory( _gvn.transform(result_mem) ); 1.356 1.357 - // Cast the result to a sharper type, since we know what clone does. 1.358 - Node* new_obj = _gvn.transform(result_val); 1.359 - Node* cast = new (C, 2) CheckCastPPNode(control(), new_obj, toop); 1.360 - push(_gvn.transform(cast)); 1.361 + push(_gvn.transform(result_val)); 1.362 1.363 return true; 1.364 } 1.365 @@ -4278,8 +4273,7 @@ 1.366 1.367 // Call StubRoutines::generic_arraycopy stub. 1.368 generate_arraycopy(TypeRawPtr::BOTTOM, T_CONFLICT, 1.369 - src, src_offset, dest, dest_offset, length, 1.370 - nargs); 1.371 + src, src_offset, dest, dest_offset, length); 1.372 1.373 // Do not let reads from the destination float above the arraycopy. 1.374 // Since we cannot type the arrays, we don't know which slices 1.375 @@ -4302,8 +4296,7 @@ 1.376 // The component types are not the same or are not recognized. Punt. 1.377 // (But, avoid the native method wrapper to JVM_ArrayCopy.) 1.378 generate_slow_arraycopy(TypePtr::BOTTOM, 1.379 - src, src_offset, dest, dest_offset, length, 1.380 - nargs); 1.381 + src, src_offset, dest, dest_offset, length); 1.382 return true; 1.383 } 1.384 1.385 @@ -4360,7 +4353,7 @@ 1.386 const TypePtr* adr_type = TypeAryPtr::get_array_body_type(dest_elem); 1.387 generate_arraycopy(adr_type, dest_elem, 1.388 src, src_offset, dest, dest_offset, length, 1.389 - nargs, false, false, slow_region); 1.390 + false, false, slow_region); 1.391 1.392 return true; 1.393 } 1.394 @@ -4405,7 +4398,6 @@ 1.395 Node* src, Node* src_offset, 1.396 Node* dest, Node* dest_offset, 1.397 Node* copy_length, 1.398 - int nargs, 1.399 bool disjoint_bases, 1.400 bool length_never_negative, 1.401 RegionNode* slow_region) { 1.402 @@ -4417,7 +4409,6 @@ 1.403 1.404 Node* original_dest = dest; 1.405 AllocateArrayNode* alloc = NULL; // used for zeroing, if needed 1.406 - Node* raw_dest = NULL; // used before zeroing, if needed 1.407 bool must_clear_dest = false; 1.408 1.409 // See if this is the initialization of a newly-allocated array. 1.410 @@ -4436,15 +4427,18 @@ 1.411 // "You break it, you buy it." 1.412 InitializeNode* init = alloc->initialization(); 1.413 assert(init->is_complete(), "we just did this"); 1.414 - assert(dest->Opcode() == Op_CheckCastPP, "sanity"); 1.415 + assert(dest->is_CheckCastPP(), "sanity"); 1.416 assert(dest->in(0)->in(0) == init, "dest pinned"); 1.417 - raw_dest = dest->in(1); // grab the raw pointer! 1.418 - original_dest = dest; 1.419 - dest = raw_dest; 1.420 + 1.421 + // Cast to Object for arraycopy. 1.422 + // We can't use the original CheckCastPP since it should be moved 1.423 + // after the arraycopy to prevent stores flowing above it. 1.424 + Node* new_obj = new(C, 2) CheckCastPPNode(dest->in(0), dest->in(1), 1.425 + TypeInstPtr::NOTNULL); 1.426 + dest = _gvn.transform(new_obj); 1.427 + // Substitute in the locally valid dest_oop. 1.428 + replace_in_map(original_dest, dest); 1.429 adr_type = TypeRawPtr::BOTTOM; // all initializations are into raw memory 1.430 - // Decouple the original InitializeNode, turning it into a simple membar. 1.431 - // We will build a new one at the end of this routine. 1.432 - init->set_req(InitializeNode::RawAddress, top()); 1.433 // From this point on, every exit path is responsible for 1.434 // initializing any non-copied parts of the object to zero. 1.435 must_clear_dest = true; 1.436 @@ -4487,7 +4481,7 @@ 1.437 assert(!must_clear_dest, ""); 1.438 Node* cv = generate_generic_arraycopy(adr_type, 1.439 src, src_offset, dest, dest_offset, 1.440 - copy_length, nargs); 1.441 + copy_length); 1.442 if (cv == NULL) cv = intcon(-1); // failure (no stub available) 1.443 checked_control = control(); 1.444 checked_i_o = i_o(); 1.445 @@ -4519,6 +4513,14 @@ 1.446 } 1.447 } 1.448 1.449 + // Use a secondary InitializeNode as raw memory barrier. 1.450 + // Currently it is needed only on this path since other 1.451 + // paths have stub or runtime calls as raw memory barriers. 1.452 + InitializeNode* init = insert_mem_bar_volatile(Op_Initialize, 1.453 + Compile::AliasIdxRaw, 1.454 + top())->as_Initialize(); 1.455 + init->set_complete(&_gvn); // (there is no corresponding AllocateNode) 1.456 + 1.457 // Present the results of the fast call. 1.458 result_region->init_req(zero_path, control()); 1.459 result_i_o ->init_req(zero_path, i_o()); 1.460 @@ -4637,8 +4639,7 @@ 1.461 Node* cv = generate_checkcast_arraycopy(adr_type, 1.462 dest_elem_klass, 1.463 src, src_offset, dest, dest_offset, 1.464 - copy_length, 1.465 - nargs); 1.466 + copy_length); 1.467 if (cv == NULL) cv = intcon(-1); // failure (no stub available) 1.468 checked_control = control(); 1.469 checked_i_o = i_o(); 1.470 @@ -4700,8 +4701,8 @@ 1.471 slow_i_o2 ->init_req(1, slow_i_o); 1.472 slow_mem2 ->init_req(1, slow_mem); 1.473 slow_reg2 ->init_req(2, control()); 1.474 - slow_i_o2 ->init_req(2, i_o()); 1.475 - slow_mem2 ->init_req(2, memory(adr_type)); 1.476 + slow_i_o2 ->init_req(2, checked_i_o); 1.477 + slow_mem2 ->init_req(2, checked_mem); 1.478 1.479 slow_control = _gvn.transform(slow_reg2); 1.480 slow_i_o = _gvn.transform(slow_i_o2); 1.481 @@ -4746,21 +4747,9 @@ 1.482 alloc->in(AllocateNode::AllocSize)); 1.483 } 1.484 1.485 - if (dest != original_dest) { 1.486 - // Promote from rawptr to oop, so it looks right in the call's GC map. 1.487 - dest = _gvn.transform( new(C,2) CheckCastPPNode(control(), dest, 1.488 - TypeInstPtr::NOTNULL) ); 1.489 - 1.490 - // Edit the call's debug-info to avoid referring to original_dest. 1.491 - // (The problem with original_dest is that it isn't ready until 1.492 - // after the InitializeNode completes, but this stuff is before.) 1.493 - // Substitute in the locally valid dest_oop. 1.494 - replace_in_map(original_dest, dest); 1.495 - } 1.496 - 1.497 generate_slow_arraycopy(adr_type, 1.498 src, src_offset, dest, dest_offset, 1.499 - copy_length, nargs); 1.500 + copy_length); 1.501 1.502 result_region->init_req(slow_call_path, control()); 1.503 result_i_o ->init_req(slow_call_path, i_o()); 1.504 @@ -4780,16 +4769,16 @@ 1.505 1.506 if (dest != original_dest) { 1.507 // Pin the "finished" array node after the arraycopy/zeroing operations. 1.508 - // Use a secondary InitializeNode memory barrier. 1.509 - InitializeNode* init = insert_mem_bar_volatile(Op_Initialize, 1.510 - Compile::AliasIdxRaw, 1.511 - raw_dest)->as_Initialize(); 1.512 - init->set_complete(&_gvn); // (there is no corresponding AllocateNode) 1.513 _gvn.hash_delete(original_dest); 1.514 original_dest->set_req(0, control()); 1.515 + // Replace raw memory edge with new CheckCastPP to have a live oop 1.516 + // at safepoints instead of raw value. 1.517 + assert(dest->is_CheckCastPP() && dest->in(1) == original_dest->in(1), "sanity"); 1.518 + original_dest->set_req(1, dest); // cast to the original type 1.519 _gvn.hash_find_insert(original_dest); // put back into GVN table 1.520 + // Restore in the locally valid dest_oop. 1.521 + replace_in_map(dest, original_dest); 1.522 } 1.523 - 1.524 // The memory edges above are precise in order to model effects around 1.525 // array copies accurately to allow value numbering of field loads around 1.526 // arraycopy. Such field loads, both before and after, are common in Java 1.527 @@ -5073,16 +5062,13 @@ 1.528 LibraryCallKit::generate_slow_arraycopy(const TypePtr* adr_type, 1.529 Node* src, Node* src_offset, 1.530 Node* dest, Node* dest_offset, 1.531 - Node* copy_length, 1.532 - int nargs) { 1.533 - _sp += nargs; // any deopt will start just before call to enclosing method 1.534 + Node* copy_length) { 1.535 Node* call = make_runtime_call(RC_NO_LEAF | RC_UNCOMMON, 1.536 OptoRuntime::slow_arraycopy_Type(), 1.537 OptoRuntime::slow_arraycopy_Java(), 1.538 "slow_arraycopy", adr_type, 1.539 src, src_offset, dest, dest_offset, 1.540 copy_length); 1.541 - _sp -= nargs; 1.542 1.543 // Handle exceptions thrown by this fellow: 1.544 make_slow_call_ex(call, env()->Throwable_klass(), false); 1.545 @@ -5094,8 +5080,7 @@ 1.546 Node* dest_elem_klass, 1.547 Node* src, Node* src_offset, 1.548 Node* dest, Node* dest_offset, 1.549 - Node* copy_length, 1.550 - int nargs) { 1.551 + Node* copy_length) { 1.552 if (stopped()) return NULL; 1.553 1.554 address copyfunc_addr = StubRoutines::checkcast_arraycopy(); 1.555 @@ -5136,8 +5121,7 @@ 1.556 LibraryCallKit::generate_generic_arraycopy(const TypePtr* adr_type, 1.557 Node* src, Node* src_offset, 1.558 Node* dest, Node* dest_offset, 1.559 - Node* copy_length, 1.560 - int nargs) { 1.561 + Node* copy_length) { 1.562 if (stopped()) return NULL; 1.563 1.564 address copyfunc_addr = StubRoutines::generic_arraycopy();