src/share/vm/opto/memnode.cpp

changeset 5658
edb5ab0f3fe5
parent 5317
3aa636f2a743
child 5710
884ed7a10f09
     1.1 --- a/src/share/vm/opto/memnode.cpp	Mon Sep 09 19:53:28 2013 +0200
     1.2 +++ b/src/share/vm/opto/memnode.cpp	Tue Sep 10 14:51:48 2013 -0700
     1.3 @@ -962,6 +962,19 @@
     1.4    return (uintptr_t)in(Control) + (uintptr_t)in(Memory) + (uintptr_t)in(Address);
     1.5  }
     1.6  
     1.7 +static bool skip_through_membars(Compile::AliasType* atp, const TypeInstPtr* tp, bool eliminate_boxing) {
     1.8 +  if ((atp != NULL) && (atp->index() >= Compile::AliasIdxRaw)) {
     1.9 +    bool non_volatile = (atp->field() != NULL) && !atp->field()->is_volatile();
    1.10 +    bool is_stable_ary = FoldStableValues &&
    1.11 +                         (tp != NULL) && (tp->isa_aryptr() != NULL) &&
    1.12 +                         tp->isa_aryptr()->is_stable();
    1.13 +
    1.14 +    return (eliminate_boxing && non_volatile) || is_stable_ary;
    1.15 +  }
    1.16 +
    1.17 +  return false;
    1.18 +}
    1.19 +
    1.20  //---------------------------can_see_stored_value------------------------------
    1.21  // This routine exists to make sure this set of tests is done the same
    1.22  // everywhere.  We need to make a coordinated change: first LoadNode::Ideal
    1.23 @@ -976,11 +989,9 @@
    1.24    const TypeInstPtr* tp = phase->type(ld_adr)->isa_instptr();
    1.25    Compile::AliasType* atp = (tp != NULL) ? phase->C->alias_type(tp) : NULL;
    1.26    // This is more general than load from boxing objects.
    1.27 -  if (phase->C->eliminate_boxing() && (atp != NULL) &&
    1.28 -      (atp->index() >= Compile::AliasIdxRaw) &&
    1.29 -      (atp->field() != NULL) && !atp->field()->is_volatile()) {
    1.30 +  if (skip_through_membars(atp, tp, phase->C->eliminate_boxing())) {
    1.31      uint alias_idx = atp->index();
    1.32 -    bool final = atp->field()->is_final();
    1.33 +    bool final = !atp->is_rewritable();
    1.34      Node* result = NULL;
    1.35      Node* current = st;
    1.36      // Skip through chains of MemBarNodes checking the MergeMems for
    1.37 @@ -1015,7 +1026,6 @@
    1.38      }
    1.39    }
    1.40  
    1.41 -
    1.42    // Loop around twice in the case Load -> Initialize -> Store.
    1.43    // (See PhaseIterGVN::add_users_to_worklist, which knows about this case.)
    1.44    for (int trip = 0; trip <= 1; trip++) {
    1.45 @@ -1577,6 +1587,40 @@
    1.46    return NULL;
    1.47  }
    1.48  
    1.49 +// Try to constant-fold a stable array element.
    1.50 +static const Type* fold_stable_ary_elem(const TypeAryPtr* ary, int off, BasicType loadbt) {
    1.51 +  assert(ary->is_stable(), "array should be stable");
    1.52 +
    1.53 +  if (ary->const_oop() != NULL) {
    1.54 +    // Decode the results of GraphKit::array_element_address.
    1.55 +    ciArray* aobj = ary->const_oop()->as_array();
    1.56 +    ciConstant con = aobj->element_value_by_offset(off);
    1.57 +
    1.58 +    if (con.basic_type() != T_ILLEGAL && !con.is_null_or_zero()) {
    1.59 +      const Type* con_type = Type::make_from_constant(con);
    1.60 +      if (con_type != NULL) {
    1.61 +        if (con_type->isa_aryptr()) {
    1.62 +          // Join with the array element type, in case it is also stable.
    1.63 +          int dim = ary->stable_dimension();
    1.64 +          con_type = con_type->is_aryptr()->cast_to_stable(true, dim-1);
    1.65 +        }
    1.66 +        if (loadbt == T_NARROWOOP && con_type->isa_oopptr()) {
    1.67 +          con_type = con_type->make_narrowoop();
    1.68 +        }
    1.69 +#ifndef PRODUCT
    1.70 +        if (TraceIterativeGVN) {
    1.71 +          tty->print("FoldStableValues: array element [off=%d]: con_type=", off);
    1.72 +          con_type->dump(); tty->cr();
    1.73 +        }
    1.74 +#endif //PRODUCT
    1.75 +        return con_type;
    1.76 +      }
    1.77 +    }
    1.78 +  }
    1.79 +
    1.80 +  return NULL;
    1.81 +}
    1.82 +
    1.83  //------------------------------Value-----------------------------------------
    1.84  const Type *LoadNode::Value( PhaseTransform *phase ) const {
    1.85    // Either input is TOP ==> the result is TOP
    1.86 @@ -1591,8 +1635,31 @@
    1.87    Compile* C = phase->C;
    1.88  
    1.89    // Try to guess loaded type from pointer type
    1.90 -  if (tp->base() == Type::AryPtr) {
    1.91 -    const Type *t = tp->is_aryptr()->elem();
    1.92 +  if (tp->isa_aryptr()) {
    1.93 +    const TypeAryPtr* ary = tp->is_aryptr();
    1.94 +    const Type *t = ary->elem();
    1.95 +
    1.96 +    // Determine whether the reference is beyond the header or not, by comparing
    1.97 +    // the offset against the offset of the start of the array's data.
    1.98 +    // Different array types begin at slightly different offsets (12 vs. 16).
    1.99 +    // We choose T_BYTE as an example base type that is least restrictive
   1.100 +    // as to alignment, which will therefore produce the smallest
   1.101 +    // possible base offset.
   1.102 +    const int min_base_off = arrayOopDesc::base_offset_in_bytes(T_BYTE);
   1.103 +    const bool off_beyond_header = ((uint)off >= (uint)min_base_off);
   1.104 +
   1.105 +    // Try to constant-fold a stable array element.
   1.106 +    if (FoldStableValues && ary->is_stable()) {
   1.107 +      // Make sure the reference is not into the header
   1.108 +      if (off_beyond_header && off != Type::OffsetBot) {
   1.109 +        assert(adr->is_AddP() && adr->in(AddPNode::Offset)->is_Con(), "offset is a constant");
   1.110 +        const Type* con_type = fold_stable_ary_elem(ary, off, memory_type());
   1.111 +        if (con_type != NULL) {
   1.112 +          return con_type;
   1.113 +        }
   1.114 +      }
   1.115 +    }
   1.116 +
   1.117      // Don't do this for integer types. There is only potential profit if
   1.118      // the element type t is lower than _type; that is, for int types, if _type is
   1.119      // more restrictive than t.  This only happens here if one is short and the other
   1.120 @@ -1613,14 +1680,7 @@
   1.121          && Opcode() != Op_LoadKlass && Opcode() != Op_LoadNKlass) {
   1.122        // t might actually be lower than _type, if _type is a unique
   1.123        // concrete subclass of abstract class t.
   1.124 -      // Make sure the reference is not into the header, by comparing
   1.125 -      // the offset against the offset of the start of the array's data.
   1.126 -      // Different array types begin at slightly different offsets (12 vs. 16).
   1.127 -      // We choose T_BYTE as an example base type that is least restrictive
   1.128 -      // as to alignment, which will therefore produce the smallest
   1.129 -      // possible base offset.
   1.130 -      const int min_base_off = arrayOopDesc::base_offset_in_bytes(T_BYTE);
   1.131 -      if ((uint)off >= (uint)min_base_off) {  // is the offset beyond the header?
   1.132 +      if (off_beyond_header) {  // is the offset beyond the header?
   1.133          const Type* jt = t->join(_type);
   1.134          // In any case, do not allow the join, per se, to empty out the type.
   1.135          if (jt->empty() && !t->empty()) {

mercurial