src/share/vm/opto/library_call.cpp

changeset 1268
acba6af809c8
parent 1262
bf3489cc0aa0
child 1271
4325cdaa78ad
     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();

mercurial