6880053: assert(alloc_obj->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL)

Thu, 10 Sep 2009 18:18:06 -0700

author
kvn
date
Thu, 10 Sep 2009 18:18:06 -0700
changeset 1393
c7e94e8fff43
parent 1392
159d56b94894
child 1394
a6f533fc33e0
child 1420
685e959d09ea

6880053: assert(alloc_obj->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL)
Summary: Removed second CheckCastPP and use MembarCPUOrder after arraycopy to cloned object.
Reviewed-by: never

src/share/vm/opto/library_call.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/type.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/type.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/opto/library_call.cpp	Thu Sep 10 10:36:24 2009 -0700
     1.2 +++ b/src/share/vm/opto/library_call.cpp	Thu Sep 10 18:18:06 2009 -0700
     1.3 @@ -3894,7 +3894,6 @@
     1.4    assert(obj_size != NULL, "");
     1.5    Node* raw_obj = alloc_obj->in(1);
     1.6    assert(alloc_obj->is_CheckCastPP() && raw_obj->is_Proj() && raw_obj->in(0)->is_Allocate(), "");
     1.7 -  assert(alloc_obj->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL, "should be more precise than Object");
     1.8  
     1.9    if (ReduceBulkZeroing) {
    1.10      // We will be completely responsible for initializing this object -
    1.11 @@ -3904,19 +3903,10 @@
    1.12      guarantee(alloc != NULL && alloc->maybe_set_complete(&_gvn), "");
    1.13    }
    1.14  
    1.15 -  // Cast to Object for arraycopy.
    1.16 -  // We can't use the original CheckCastPP since it should be moved
    1.17 -  // after the arraycopy to prevent stores flowing above it.
    1.18 -  Node* new_obj = new(C, 2) CheckCastPPNode(alloc_obj->in(0), raw_obj,
    1.19 -                                            TypeInstPtr::NOTNULL);
    1.20 -  new_obj = _gvn.transform(new_obj);
    1.21 -  // Substitute in the locally valid dest_oop.
    1.22 -  replace_in_map(alloc_obj, new_obj);
    1.23 -
    1.24    // Copy the fastest available way.
    1.25    // TODO: generate fields copies for small objects instead.
    1.26    Node* src  = obj;
    1.27 -  Node* dest = new_obj;
    1.28 +  Node* dest = alloc_obj;
    1.29    Node* size = _gvn.transform(obj_size);
    1.30  
    1.31    // Exclude the header but include array length to copy by 8 bytes words.
    1.32 @@ -3962,7 +3952,7 @@
    1.33      int raw_adr_idx = Compile::AliasIdxRaw;
    1.34      post_barrier(control(),
    1.35                   memory(raw_adr_type),
    1.36 -                 new_obj,
    1.37 +                 alloc_obj,
    1.38                   no_particular_field,
    1.39                   raw_adr_idx,
    1.40                   no_particular_value,
    1.41 @@ -3970,16 +3960,8 @@
    1.42                   false);
    1.43    }
    1.44  
    1.45 -  // Move the original CheckCastPP after arraycopy.
    1.46 -  _gvn.hash_delete(alloc_obj);
    1.47 -  alloc_obj->set_req(0, control());
    1.48 -  // Replace raw memory edge with new CheckCastPP to have a live oop
    1.49 -  // at safepoints instead of raw value.
    1.50 -  assert(new_obj->is_CheckCastPP() && new_obj->in(1) == alloc_obj->in(1), "sanity");
    1.51 -  alloc_obj->set_req(1, new_obj);    // cast to the original type
    1.52 -  _gvn.hash_find_insert(alloc_obj);  // put back into GVN table
    1.53 -  // Restore in the locally valid dest_oop.
    1.54 -  replace_in_map(new_obj, alloc_obj);
    1.55 +  // Do not let reads from the cloned object float above the arraycopy.
    1.56 +  insert_mem_bar(Op_MemBarCPUOrder);
    1.57  }
    1.58  
    1.59  //------------------------inline_native_clone----------------------------
    1.60 @@ -4448,17 +4430,7 @@
    1.61      InitializeNode* init = alloc->initialization();
    1.62      assert(init->is_complete(), "we just did this");
    1.63      assert(dest->is_CheckCastPP(), "sanity");
    1.64 -    assert(dest->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL, "type should be more precise than Object");
    1.65      assert(dest->in(0)->in(0) == init, "dest pinned");
    1.66 -
    1.67 -    // Cast to Object for arraycopy.
    1.68 -    // We can't use the original CheckCastPP since it should be moved
    1.69 -    // after the arraycopy to prevent stores flowing above it.
    1.70 -    Node* new_obj = new(C, 2) CheckCastPPNode(dest->in(0), dest->in(1),
    1.71 -                                              TypeInstPtr::NOTNULL);
    1.72 -    dest = _gvn.transform(new_obj);
    1.73 -    // Substitute in the locally valid dest_oop.
    1.74 -    replace_in_map(original_dest, dest);
    1.75      adr_type = TypeRawPtr::BOTTOM;  // all initializations are into raw memory
    1.76      // From this point on, every exit path is responsible for
    1.77      // initializing any non-copied parts of the object to zero.
    1.78 @@ -4788,18 +4760,6 @@
    1.79    set_i_o(     _gvn.transform(result_i_o)    );
    1.80    set_memory(  _gvn.transform(result_memory), adr_type );
    1.81  
    1.82 -  if (dest != original_dest) {
    1.83 -    // Pin the "finished" array node after the arraycopy/zeroing operations.
    1.84 -    _gvn.hash_delete(original_dest);
    1.85 -    original_dest->set_req(0, control());
    1.86 -    // Replace raw memory edge with new CheckCastPP to have a live oop
    1.87 -    // at safepoints instead of raw value.
    1.88 -    assert(dest->is_CheckCastPP() && dest->in(1) == original_dest->in(1), "sanity");
    1.89 -    original_dest->set_req(1, dest);       // cast to the original type
    1.90 -    _gvn.hash_find_insert(original_dest);  // put back into GVN table
    1.91 -    // Restore in the locally valid dest_oop.
    1.92 -    replace_in_map(dest, original_dest);
    1.93 -  }
    1.94    // The memory edges above are precise in order to model effects around
    1.95    // array copies accurately to allow value numbering of field loads around
    1.96    // arraycopy.  Such field loads, both before and after, are common in Java
    1.97 @@ -4810,7 +4770,9 @@
    1.98    // The next memory barrier is added to avoid it. If the arraycopy can be
    1.99    // optimized away (which it can, sometimes) then we can manually remove
   1.100    // the membar also.
   1.101 -  if (InsertMemBarAfterArraycopy)
   1.102 +  //
   1.103 +  // Do not let reads from the cloned object float above the arraycopy.
   1.104 +  if (InsertMemBarAfterArraycopy || alloc != NULL)
   1.105      insert_mem_bar(Op_MemBarCPUOrder);
   1.106  }
   1.107  
     2.1 --- a/src/share/vm/opto/type.cpp	Thu Sep 10 10:36:24 2009 -0700
     2.2 +++ b/src/share/vm/opto/type.cpp	Thu Sep 10 18:18:06 2009 -0700
     2.3 @@ -2236,12 +2236,12 @@
     2.4  
     2.5  //------------------------------make-------------------------------------------
     2.6  const TypeOopPtr *TypeOopPtr::make(PTR ptr,
     2.7 -                                   int offset) {
     2.8 +                                   int offset, int instance_id) {
     2.9    assert(ptr != Constant, "no constant generic pointers");
    2.10    ciKlass*  k = ciKlassKlass::make();
    2.11    bool      xk = false;
    2.12    ciObject* o = NULL;
    2.13 -  return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, xk, o, offset, InstanceBot))->hashcons();
    2.14 +  return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, xk, o, offset, instance_id))->hashcons();
    2.15  }
    2.16  
    2.17  
    2.18 @@ -2330,7 +2330,8 @@
    2.19  
    2.20    case OopPtr: {                 // Meeting to other OopPtrs
    2.21      const TypeOopPtr *tp = t->is_oopptr();
    2.22 -    return make( meet_ptr(tp->ptr()), meet_offset(tp->offset()) );
    2.23 +    int instance_id = meet_instance_id(tp->instance_id());
    2.24 +    return make( meet_ptr(tp->ptr()), meet_offset(tp->offset()), instance_id );
    2.25    }
    2.26  
    2.27    case InstPtr:                  // For these, flip the call around to cut down
    2.28 @@ -2801,7 +2802,7 @@
    2.29  
    2.30    case OopPtr: {                // Meeting to OopPtrs
    2.31      // Found a OopPtr type vs self-InstPtr type
    2.32 -    const TypePtr *tp = t->is_oopptr();
    2.33 +    const TypeOopPtr *tp = t->is_oopptr();
    2.34      int offset = meet_offset(tp->offset());
    2.35      PTR ptr = meet_ptr(tp->ptr());
    2.36      switch (tp->ptr()) {
    2.37 @@ -2812,8 +2813,10 @@
    2.38                    (ptr == Constant ? const_oop() : NULL), offset, instance_id);
    2.39      }
    2.40      case NotNull:
    2.41 -    case BotPTR:
    2.42 -      return TypeOopPtr::make(ptr, offset);
    2.43 +    case BotPTR: {
    2.44 +      int instance_id = meet_instance_id(tp->instance_id());
    2.45 +      return TypeOopPtr::make(ptr, offset, instance_id);
    2.46 +    }
    2.47      default: typerr(t);
    2.48      }
    2.49    }
    2.50 @@ -3259,7 +3262,7 @@
    2.51  
    2.52    case OopPtr: {                // Meeting to OopPtrs
    2.53      // Found a OopPtr type vs self-AryPtr type
    2.54 -    const TypePtr *tp = t->is_oopptr();
    2.55 +    const TypeOopPtr *tp = t->is_oopptr();
    2.56      int offset = meet_offset(tp->offset());
    2.57      PTR ptr = meet_ptr(tp->ptr());
    2.58      switch (tp->ptr()) {
    2.59 @@ -3270,8 +3273,10 @@
    2.60                    _ary, _klass, _klass_is_exact, offset, instance_id);
    2.61      }
    2.62      case BotPTR:
    2.63 -    case NotNull:
    2.64 -      return TypeOopPtr::make(ptr, offset);
    2.65 +    case NotNull: {
    2.66 +      int instance_id = meet_instance_id(tp->instance_id());
    2.67 +      return TypeOopPtr::make(ptr, offset, instance_id);
    2.68 +    }
    2.69      default: ShouldNotReachHere();
    2.70      }
    2.71    }
     3.1 --- a/src/share/vm/opto/type.hpp	Thu Sep 10 10:36:24 2009 -0700
     3.2 +++ b/src/share/vm/opto/type.hpp	Thu Sep 10 18:18:06 2009 -0700
     3.3 @@ -714,7 +714,7 @@
     3.4    static const TypeOopPtr* make_from_constant(ciObject* o);
     3.5  
     3.6    // Make a generic (unclassed) pointer to an oop.
     3.7 -  static const TypeOopPtr* make(PTR ptr, int offset);
     3.8 +  static const TypeOopPtr* make(PTR ptr, int offset, int instance_id = InstanceBot);
     3.9  
    3.10    ciObject* const_oop()    const { return _const_oop; }
    3.11    virtual ciKlass* klass() const { return _klass;     }

mercurial