8031754: Type speculation should favor profile data from outermost inlined method

Fri, 14 Mar 2014 17:15:32 +0100

author
roland
date
Fri, 14 Mar 2014 17:15:32 +0100
changeset 6380
62825ea7e51f
parent 6377
b8413a9cbb84
child 6381
8ef3428f54b6

8031754: Type speculation should favor profile data from outermost inlined method
Summary: favor profile data coming from outer most method
Reviewed-by: kvn, twisti

src/share/vm/opto/c2_globals.hpp file | annotate | diff | comparison | revisions
src/share/vm/opto/graphKit.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/c2_globals.hpp	Tue Feb 25 18:16:24 2014 +0100
     1.2 +++ b/src/share/vm/opto/c2_globals.hpp	Fri Mar 14 17:15:32 2014 +0100
     1.3 @@ -644,7 +644,12 @@
     1.4            "Propagate type improvements in callers of inlinee if possible")  \
     1.5                                                                              \
     1.6    experimental(bool, UseTypeSpeculation, false,                             \
     1.7 -          "Speculatively propagate types from profiles")
     1.8 +          "Speculatively propagate types from profiles")                    \
     1.9 +                                                                            \
    1.10 +  diagnostic(bool, UseInlineDepthForSpeculativeTypes, true,                 \
    1.11 +          "Carry inline depth of profile point with speculative type "      \
    1.12 +          "and give priority to profiling from lower inline depth")         \
    1.13 +
    1.14  
    1.15  C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG)
    1.16  
     2.1 --- a/src/share/vm/opto/graphKit.cpp	Tue Feb 25 18:16:24 2014 +0100
     2.2 +++ b/src/share/vm/opto/graphKit.cpp	Fri Mar 14 17:15:32 2014 +0100
     2.3 @@ -2109,30 +2109,33 @@
     2.4   * @return           node with improved type
     2.5   */
     2.6  Node* GraphKit::record_profile_for_speculation(Node* n, ciKlass* exact_kls) {
     2.7 -  const TypeOopPtr* current_type = _gvn.type(n)->isa_oopptr();
     2.8 +  const Type* current_type = _gvn.type(n);
     2.9    assert(UseTypeSpeculation, "type speculation must be on");
    2.10 -  if (exact_kls != NULL &&
    2.11 -      // nothing to improve if type is already exact
    2.12 -      (current_type == NULL ||
    2.13 -       (!current_type->klass_is_exact() &&
    2.14 -        (current_type->speculative() == NULL ||
    2.15 -         !current_type->speculative()->klass_is_exact())))) {
    2.16 +
    2.17 +  const TypeOopPtr* speculative = current_type->speculative();
    2.18 +
    2.19 +  if (current_type->would_improve_type(exact_kls, jvms()->depth())) {
    2.20      const TypeKlassPtr* tklass = TypeKlassPtr::make(exact_kls);
    2.21      const TypeOopPtr* xtype = tklass->as_instance_type();
    2.22      assert(xtype->klass_is_exact(), "Should be exact");
    2.23 -
    2.24 +    // record the new speculative type's depth
    2.25 +    speculative = xtype->with_inline_depth(jvms()->depth());
    2.26 +  }
    2.27 +
    2.28 +  if (speculative != current_type->speculative()) {
    2.29      // Build a type with a speculative type (what we think we know
    2.30      // about the type but will need a guard when we use it)
    2.31 -    const TypeOopPtr* spec_type = TypeOopPtr::make(TypePtr::BotPTR, Type::OffsetBot, TypeOopPtr::InstanceBot, xtype);
    2.32 -    // We're changing the type, we need a new cast node to carry the
    2.33 -    // new type. The new type depends on the control: what profiling
    2.34 -    // tells us is only valid from here as far as we can tell.
    2.35 -    Node* cast = new(C) CastPPNode(n, spec_type);
    2.36 -    cast->init_req(0, control());
    2.37 +    const TypeOopPtr* spec_type = TypeOopPtr::make(TypePtr::BotPTR, Type::OffsetBot, TypeOopPtr::InstanceBot, speculative);
    2.38 +    // We're changing the type, we need a new CheckCast node to carry
    2.39 +    // the new type. The new type depends on the control: what
    2.40 +    // profiling tells us is only valid from here as far as we can
    2.41 +    // tell.
    2.42 +    Node* cast = new(C) CheckCastPPNode(control(), n, current_type->remove_speculative()->join_speculative(spec_type));
    2.43      cast = _gvn.transform(cast);
    2.44      replace_in_map(n, cast);
    2.45      n = cast;
    2.46    }
    2.47 +
    2.48    return n;
    2.49  }
    2.50  
     3.1 --- a/src/share/vm/opto/type.cpp	Tue Feb 25 18:16:24 2014 +0100
     3.2 +++ b/src/share/vm/opto/type.cpp	Fri Mar 14 17:15:32 2014 +0100
     3.3 @@ -2457,7 +2457,7 @@
     3.4  const TypeOopPtr *TypeOopPtr::BOTTOM;
     3.5  
     3.6  //------------------------------TypeOopPtr-------------------------------------
     3.7 -TypeOopPtr::TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id, const TypeOopPtr* speculative)
     3.8 +TypeOopPtr::TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id, const TypeOopPtr* speculative, int inline_depth)
     3.9    : TypePtr(t, ptr, offset),
    3.10      _const_oop(o), _klass(k),
    3.11      _klass_is_exact(xk),
    3.12 @@ -2465,7 +2465,8 @@
    3.13      _is_ptr_to_narrowklass(false),
    3.14      _is_ptr_to_boxed_value(false),
    3.15      _instance_id(instance_id),
    3.16 -    _speculative(speculative) {
    3.17 +    _speculative(speculative),
    3.18 +    _inline_depth(inline_depth){
    3.19    if (Compile::current()->eliminate_boxing() && (t == InstPtr) &&
    3.20        (offset > 0) && xk && (k != 0) && k->is_instance_klass()) {
    3.21      _is_ptr_to_boxed_value = k->as_instance_klass()->is_boxed_value_offset(offset);
    3.22 @@ -2532,12 +2533,12 @@
    3.23  
    3.24  //------------------------------make-------------------------------------------
    3.25  const TypeOopPtr *TypeOopPtr::make(PTR ptr,
    3.26 -                                   int offset, int instance_id, const TypeOopPtr* speculative) {
    3.27 +                                   int offset, int instance_id, const TypeOopPtr* speculative, int inline_depth) {
    3.28    assert(ptr != Constant, "no constant generic pointers");
    3.29    ciKlass*  k = Compile::current()->env()->Object_klass();
    3.30    bool      xk = false;
    3.31    ciObject* o = NULL;
    3.32 -  return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, xk, o, offset, instance_id, speculative))->hashcons();
    3.33 +  return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, xk, o, offset, instance_id, speculative, inline_depth))->hashcons();
    3.34  }
    3.35  
    3.36  
    3.37 @@ -2545,7 +2546,7 @@
    3.38  const Type *TypeOopPtr::cast_to_ptr_type(PTR ptr) const {
    3.39    assert(_base == OopPtr, "subclass must override cast_to_ptr_type");
    3.40    if( ptr == _ptr ) return this;
    3.41 -  return make(ptr, _offset, _instance_id, _speculative);
    3.42 +  return make(ptr, _offset, _instance_id, _speculative, _inline_depth);
    3.43  }
    3.44  
    3.45  //-----------------------------cast_to_instance_id----------------------------
    3.46 @@ -2642,7 +2643,7 @@
    3.47      case AnyNull: {
    3.48        int instance_id = meet_instance_id(InstanceTop);
    3.49        const TypeOopPtr* speculative = _speculative;
    3.50 -      return make(ptr, offset, instance_id, speculative);
    3.51 +      return make(ptr, offset, instance_id, speculative, _inline_depth);
    3.52      }
    3.53      case BotPTR:
    3.54      case NotNull:
    3.55 @@ -2655,7 +2656,8 @@
    3.56      const TypeOopPtr *tp = t->is_oopptr();
    3.57      int instance_id = meet_instance_id(tp->instance_id());
    3.58      const TypeOopPtr* speculative = xmeet_speculative(tp);
    3.59 -    return make(meet_ptr(tp->ptr()), meet_offset(tp->offset()), instance_id, speculative);
    3.60 +    int depth = meet_inline_depth(tp->inline_depth());
    3.61 +    return make(meet_ptr(tp->ptr()), meet_offset(tp->offset()), instance_id, speculative, depth);
    3.62    }
    3.63  
    3.64    case InstPtr:                  // For these, flip the call around to cut down
    3.65 @@ -2672,7 +2674,7 @@
    3.66  const Type *TypeOopPtr::xdual() const {
    3.67    assert(klass() == Compile::current()->env()->Object_klass(), "no klasses here");
    3.68    assert(const_oop() == NULL,             "no constants here");
    3.69 -  return new TypeOopPtr(_base, dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance_id(), dual_speculative());
    3.70 +  return new TypeOopPtr(_base, dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance_id(), dual_speculative(), dual_inline_depth());
    3.71  }
    3.72  
    3.73  //--------------------------make_from_klass_common-----------------------------
    3.74 @@ -2763,7 +2765,7 @@
    3.75      } else if (!o->should_be_constant()) {
    3.76        return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0);
    3.77      }
    3.78 -    const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0, InstanceBot, NULL, is_autobox_cache);
    3.79 +    const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0, InstanceBot, NULL, InlineDepthBottom, is_autobox_cache);
    3.80      return arr;
    3.81    } else if (klass->is_type_array_klass()) {
    3.82      // Element is an typeArray
    3.83 @@ -2852,7 +2854,8 @@
    3.84    const TypeOopPtr *a = (const TypeOopPtr*)t;
    3.85    if (_klass_is_exact != a->_klass_is_exact ||
    3.86        _instance_id != a->_instance_id ||
    3.87 -      !eq_speculative(a))  return false;
    3.88 +      !eq_speculative(a) ||
    3.89 +      _inline_depth != a->_inline_depth)  return false;
    3.90    ciObject* one = const_oop();
    3.91    ciObject* two = a->const_oop();
    3.92    if (one == NULL || two == NULL) {
    3.93 @@ -2870,6 +2873,7 @@
    3.94      _klass_is_exact +
    3.95      _instance_id +
    3.96      hash_speculative() +
    3.97 +    _inline_depth +
    3.98      TypePtr::hash();
    3.99  }
   3.100  
   3.101 @@ -2890,6 +2894,7 @@
   3.102    else if (_instance_id != InstanceBot)
   3.103      st->print(",iid=%d",_instance_id);
   3.104  
   3.105 +  dump_inline_depth(st);
   3.106    dump_speculative(st);
   3.107  }
   3.108  
   3.109 @@ -2903,6 +2908,16 @@
   3.110      st->print(")");
   3.111    }
   3.112  }
   3.113 +
   3.114 +void TypeOopPtr::dump_inline_depth(outputStream *st) const {
   3.115 +  if (_inline_depth != InlineDepthBottom) {
   3.116 +    if (_inline_depth == InlineDepthTop) {
   3.117 +      st->print(" (inline_depth=InlineDepthTop)");
   3.118 +    } else {
   3.119 +      st->print(" (inline_depth=%d)", _inline_depth);
   3.120 +    }
   3.121 +  }
   3.122 +}
   3.123  #endif
   3.124  
   3.125  //------------------------------singleton--------------------------------------
   3.126 @@ -2916,7 +2931,7 @@
   3.127  
   3.128  //------------------------------add_offset-------------------------------------
   3.129  const TypePtr *TypeOopPtr::add_offset(intptr_t offset) const {
   3.130 -  return make(_ptr, xadd_offset(offset), _instance_id, add_offset_speculative(offset));
   3.131 +  return make(_ptr, xadd_offset(offset), _instance_id, add_offset_speculative(offset), _inline_depth);
   3.132  }
   3.133  
   3.134  /**
   3.135 @@ -2926,7 +2941,52 @@
   3.136    if (_speculative == NULL) {
   3.137      return this;
   3.138    }
   3.139 -  return make(_ptr, _offset, _instance_id, NULL);
   3.140 +  assert(_inline_depth == InlineDepthTop || _inline_depth == InlineDepthBottom, "non speculative type shouldn't have inline depth");
   3.141 +  return make(_ptr, _offset, _instance_id, NULL, _inline_depth);
   3.142 +}
   3.143 +
   3.144 +/**
   3.145 + * Return same type but with a different inline depth (used for speculation)
   3.146 + *
   3.147 + * @param depth  depth to meet with
   3.148 + */
   3.149 +const TypeOopPtr* TypeOopPtr::with_inline_depth(int depth) const {
   3.150 +  if (!UseInlineDepthForSpeculativeTypes) {
   3.151 +    return this;
   3.152 +  }
   3.153 +  return make(_ptr, _offset, _instance_id, _speculative, depth);
   3.154 +}
   3.155 +
   3.156 +/**
   3.157 + * Check whether new profiling would improve speculative type
   3.158 + *
   3.159 + * @param   exact_kls    class from profiling
   3.160 + * @param   inline_depth inlining depth of profile point
   3.161 + *
   3.162 + * @return  true if type profile is valuable
   3.163 + */
   3.164 +bool TypeOopPtr::would_improve_type(ciKlass* exact_kls, int inline_depth) const {
   3.165 +  // no way to improve an already exact type
   3.166 +  if (klass_is_exact()) {
   3.167 +    return false;
   3.168 +  }
   3.169 +  // no profiling?
   3.170 +  if (exact_kls == NULL) {
   3.171 +    return false;
   3.172 +  }
   3.173 +  // no speculative type or non exact speculative type?
   3.174 +  if (speculative_type() == NULL) {
   3.175 +    return true;
   3.176 +  }
   3.177 +  // If the node already has an exact speculative type keep it,
   3.178 +  // unless it was provided by profiling that is at a deeper
   3.179 +  // inlining level. Profiling at a higher inlining depth is
   3.180 +  // expected to be less accurate.
   3.181 +  if (_speculative->inline_depth() == InlineDepthBottom) {
   3.182 +    return false;
   3.183 +  }
   3.184 +  assert(_speculative->inline_depth() != InlineDepthTop, "can't do the comparison");
   3.185 +  return inline_depth < _speculative->inline_depth();
   3.186  }
   3.187  
   3.188  //------------------------------meet_instance_id--------------------------------
   3.189 @@ -3029,6 +3089,21 @@
   3.190    return _speculative->hash();
   3.191  }
   3.192  
   3.193 +/**
   3.194 + * dual of the inline depth for this type (used for speculation)
   3.195 + */
   3.196 +int TypeOopPtr::dual_inline_depth() const {
   3.197 +  return -inline_depth();
   3.198 +}
   3.199 +
   3.200 +/**
   3.201 + * meet of 2 inline depth (used for speculation)
   3.202 + *
   3.203 + * @param depth  depth to meet with
   3.204 + */
   3.205 +int TypeOopPtr::meet_inline_depth(int depth) const {
   3.206 +  return MAX2(inline_depth(), depth);
   3.207 +}
   3.208  
   3.209  //=============================================================================
   3.210  // Convenience common pre-built types.
   3.211 @@ -3039,8 +3114,8 @@
   3.212  const TypeInstPtr *TypeInstPtr::KLASS;
   3.213  
   3.214  //------------------------------TypeInstPtr-------------------------------------
   3.215 -TypeInstPtr::TypeInstPtr(PTR ptr, ciKlass* k, bool xk, ciObject* o, int off, int instance_id, const TypeOopPtr* speculative)
   3.216 -  : TypeOopPtr(InstPtr, ptr, k, xk, o, off, instance_id, speculative), _name(k->name()) {
   3.217 +TypeInstPtr::TypeInstPtr(PTR ptr, ciKlass* k, bool xk, ciObject* o, int off, int instance_id, const TypeOopPtr* speculative, int inline_depth)
   3.218 +  : TypeOopPtr(InstPtr, ptr, k, xk, o, off, instance_id, speculative, inline_depth), _name(k->name()) {
   3.219     assert(k != NULL &&
   3.220            (k->is_loaded() || o == NULL),
   3.221            "cannot have constants with non-loaded klass");
   3.222 @@ -3053,7 +3128,8 @@
   3.223                                       ciObject* o,
   3.224                                       int offset,
   3.225                                       int instance_id,
   3.226 -                                     const TypeOopPtr* speculative) {
   3.227 +                                     const TypeOopPtr* speculative,
   3.228 +                                     int inline_depth) {
   3.229    assert( !k->is_loaded() || k->is_instance_klass(), "Must be for instance");
   3.230    // Either const_oop() is NULL or else ptr is Constant
   3.231    assert( (!o && ptr != Constant) || (o && ptr == Constant),
   3.232 @@ -3074,7 +3150,7 @@
   3.233  
   3.234    // Now hash this baby
   3.235    TypeInstPtr *result =
   3.236 -    (TypeInstPtr*)(new TypeInstPtr(ptr, k, xk, o ,offset, instance_id, speculative))->hashcons();
   3.237 +    (TypeInstPtr*)(new TypeInstPtr(ptr, k, xk, o ,offset, instance_id, speculative, inline_depth))->hashcons();
   3.238  
   3.239    return result;
   3.240  }
   3.241 @@ -3107,7 +3183,7 @@
   3.242    if( ptr == _ptr ) return this;
   3.243    // Reconstruct _sig info here since not a problem with later lazy
   3.244    // construction, _sig will show up on demand.
   3.245 -  return make(ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id, _speculative);
   3.246 +  return make(ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id, _speculative, _inline_depth);
   3.247  }
   3.248  
   3.249  
   3.250 @@ -3119,13 +3195,13 @@
   3.251    ciInstanceKlass* ik = _klass->as_instance_klass();
   3.252    if( (ik->is_final() || _const_oop) )  return this;  // cannot clear xk
   3.253    if( ik->is_interface() )              return this;  // cannot set xk
   3.254 -  return make(ptr(), klass(), klass_is_exact, const_oop(), _offset, _instance_id, _speculative);
   3.255 +  return make(ptr(), klass(), klass_is_exact, const_oop(), _offset, _instance_id, _speculative, _inline_depth);
   3.256  }
   3.257  
   3.258  //-----------------------------cast_to_instance_id----------------------------
   3.259  const TypeOopPtr *TypeInstPtr::cast_to_instance_id(int instance_id) const {
   3.260    if( instance_id == _instance_id ) return this;
   3.261 -  return make(_ptr, klass(), _klass_is_exact, const_oop(), _offset, instance_id, _speculative);
   3.262 +  return make(_ptr, klass(), _klass_is_exact, const_oop(), _offset, instance_id, _speculative, _inline_depth);
   3.263  }
   3.264  
   3.265  //------------------------------xmeet_unloaded---------------------------------
   3.266 @@ -3136,6 +3212,7 @@
   3.267      PTR ptr = meet_ptr(tinst->ptr());
   3.268      int instance_id = meet_instance_id(tinst->instance_id());
   3.269      const TypeOopPtr* speculative = xmeet_speculative(tinst);
   3.270 +    int depth = meet_inline_depth(tinst->inline_depth());
   3.271  
   3.272      const TypeInstPtr *loaded    = is_loaded() ? this  : tinst;
   3.273      const TypeInstPtr *unloaded  = is_loaded() ? tinst : this;
   3.274 @@ -3156,7 +3233,7 @@
   3.275        assert(loaded->ptr() != TypePtr::Null, "insanity check");
   3.276        //
   3.277        if(      loaded->ptr() == TypePtr::TopPTR ) { return unloaded; }
   3.278 -      else if (loaded->ptr() == TypePtr::AnyNull) { return TypeInstPtr::make(ptr, unloaded->klass(), false, NULL, off, instance_id, speculative); }
   3.279 +      else if (loaded->ptr() == TypePtr::AnyNull) { return TypeInstPtr::make(ptr, unloaded->klass(), false, NULL, off, instance_id, speculative, depth); }
   3.280        else if (loaded->ptr() == TypePtr::BotPTR ) { return TypeInstPtr::BOTTOM; }
   3.281        else if (loaded->ptr() == TypePtr::Constant || loaded->ptr() == TypePtr::NotNull) {
   3.282          if (unloaded->ptr() == TypePtr::BotPTR  ) { return TypeInstPtr::BOTTOM;  }
   3.283 @@ -3213,6 +3290,7 @@
   3.284      PTR ptr = meet_ptr(tp->ptr());
   3.285      int instance_id = meet_instance_id(tp->instance_id());
   3.286      const TypeOopPtr* speculative = xmeet_speculative(tp);
   3.287 +    int depth = meet_inline_depth(tp->inline_depth());
   3.288      switch (ptr) {
   3.289      case TopPTR:
   3.290      case AnyNull:                // Fall 'down' to dual of object klass
   3.291 @@ -3220,12 +3298,12 @@
   3.292        // below the centerline when the superclass is exact. We need to
   3.293        // do the same here.
   3.294        if (klass()->equals(ciEnv::current()->Object_klass()) && !klass_is_exact()) {
   3.295 -        return TypeAryPtr::make(ptr, tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id, speculative);
   3.296 +        return TypeAryPtr::make(ptr, tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id, speculative, depth);
   3.297        } else {
   3.298          // cannot subclass, so the meet has to fall badly below the centerline
   3.299          ptr = NotNull;
   3.300          instance_id = InstanceBot;
   3.301 -        return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL, offset, instance_id, speculative);
   3.302 +        return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL, offset, instance_id, speculative, depth);
   3.303        }
   3.304      case Constant:
   3.305      case NotNull:
   3.306 @@ -3240,7 +3318,7 @@
   3.307          if (klass()->equals(ciEnv::current()->Object_klass()) && !klass_is_exact()) {
   3.308            // that is, tp's array type is a subtype of my klass
   3.309            return TypeAryPtr::make(ptr, (ptr == Constant ? tp->const_oop() : NULL),
   3.310 -                                  tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id, speculative);
   3.311 +                                  tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id, speculative, depth);
   3.312          }
   3.313        }
   3.314        // The other case cannot happen, since I cannot be a subtype of an array.
   3.315 @@ -3248,7 +3326,7 @@
   3.316        if( ptr == Constant )
   3.317           ptr = NotNull;
   3.318        instance_id = InstanceBot;
   3.319 -      return make(ptr, ciEnv::current()->Object_klass(), false, NULL, offset, instance_id, speculative);
   3.320 +      return make(ptr, ciEnv::current()->Object_klass(), false, NULL, offset, instance_id, speculative, depth);
   3.321      default: typerr(t);
   3.322      }
   3.323    }
   3.324 @@ -3263,14 +3341,16 @@
   3.325      case AnyNull: {
   3.326        int instance_id = meet_instance_id(InstanceTop);
   3.327        const TypeOopPtr* speculative = xmeet_speculative(tp);
   3.328 +      int depth = meet_inline_depth(tp->inline_depth());
   3.329        return make(ptr, klass(), klass_is_exact(),
   3.330 -                  (ptr == Constant ? const_oop() : NULL), offset, instance_id, speculative);
   3.331 +                  (ptr == Constant ? const_oop() : NULL), offset, instance_id, speculative, depth);
   3.332      }
   3.333      case NotNull:
   3.334      case BotPTR: {
   3.335        int instance_id = meet_instance_id(tp->instance_id());
   3.336        const TypeOopPtr* speculative = xmeet_speculative(tp);
   3.337 -      return TypeOopPtr::make(ptr, offset, instance_id, speculative);
   3.338 +      int depth = meet_inline_depth(tp->inline_depth());
   3.339 +      return TypeOopPtr::make(ptr, offset, instance_id, speculative, depth);
   3.340      }
   3.341      default: typerr(t);
   3.342      }
   3.343 @@ -3290,7 +3370,7 @@
   3.344        int instance_id = meet_instance_id(InstanceTop);
   3.345        const TypeOopPtr* speculative = _speculative;
   3.346        return make(ptr, klass(), klass_is_exact(),
   3.347 -                  (ptr == Constant ? const_oop() : NULL), offset, instance_id, speculative);
   3.348 +                  (ptr == Constant ? const_oop() : NULL), offset, instance_id, speculative, _inline_depth);
   3.349      }
   3.350      case NotNull:
   3.351      case BotPTR:
   3.352 @@ -3322,13 +3402,14 @@
   3.353      PTR ptr = meet_ptr( tinst->ptr() );
   3.354      int instance_id = meet_instance_id(tinst->instance_id());
   3.355      const TypeOopPtr* speculative = xmeet_speculative(tinst);
   3.356 +    int depth = meet_inline_depth(tinst->inline_depth());
   3.357  
   3.358      // Check for easy case; klasses are equal (and perhaps not loaded!)
   3.359      // If we have constants, then we created oops so classes are loaded
   3.360      // and we can handle the constants further down.  This case handles
   3.361      // both-not-loaded or both-loaded classes
   3.362      if (ptr != Constant && klass()->equals(tinst->klass()) && klass_is_exact() == tinst->klass_is_exact()) {
   3.363 -      return make(ptr, klass(), klass_is_exact(), NULL, off, instance_id, speculative);
   3.364 +      return make(ptr, klass(), klass_is_exact(), NULL, off, instance_id, speculative, depth);
   3.365      }
   3.366  
   3.367      // Classes require inspection in the Java klass hierarchy.  Must be loaded.
   3.368 @@ -3392,7 +3473,7 @@
   3.369          // Find out which constant.
   3.370          o = (this_klass == klass()) ? const_oop() : tinst->const_oop();
   3.371        }
   3.372 -      return make(ptr, k, xk, o, off, instance_id, speculative);
   3.373 +      return make(ptr, k, xk, o, off, instance_id, speculative, depth);
   3.374      }
   3.375  
   3.376      // Either oop vs oop or interface vs interface or interface vs Object
   3.377 @@ -3469,7 +3550,7 @@
   3.378          else
   3.379            ptr = NotNull;
   3.380        }
   3.381 -      return make(ptr, this_klass, this_xk, o, off, instance_id, speculative);
   3.382 +      return make(ptr, this_klass, this_xk, o, off, instance_id, speculative, depth);
   3.383      } // Else classes are not equal
   3.384  
   3.385      // Since klasses are different, we require a LCA in the Java
   3.386 @@ -3480,7 +3561,7 @@
   3.387  
   3.388      // Now we find the LCA of Java classes
   3.389      ciKlass* k = this_klass->least_common_ancestor(tinst_klass);
   3.390 -    return make(ptr, k, false, NULL, off, instance_id, speculative);
   3.391 +    return make(ptr, k, false, NULL, off, instance_id, speculative, depth);
   3.392    } // End of case InstPtr
   3.393  
   3.394    } // End of switch
   3.395 @@ -3504,7 +3585,7 @@
   3.396  // Dual: do NOT dual on klasses.  This means I do NOT understand the Java
   3.397  // inheritance mechanism.
   3.398  const Type *TypeInstPtr::xdual() const {
   3.399 -  return new TypeInstPtr(dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance_id(), dual_speculative());
   3.400 +  return new TypeInstPtr(dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance_id(), dual_speculative(), dual_inline_depth());
   3.401  }
   3.402  
   3.403  //------------------------------eq---------------------------------------------
   3.404 @@ -3561,6 +3642,7 @@
   3.405    else if (_instance_id != InstanceBot)
   3.406      st->print(",iid=%d",_instance_id);
   3.407  
   3.408 +  dump_inline_depth(st);
   3.409    dump_speculative(st);
   3.410  }
   3.411  #endif
   3.412 @@ -3574,7 +3656,15 @@
   3.413    if (_speculative == NULL) {
   3.414      return this;
   3.415    }
   3.416 -  return make(_ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id, NULL);
   3.417 +  assert(_inline_depth == InlineDepthTop || _inline_depth == InlineDepthBottom, "non speculative type shouldn't have inline depth");
   3.418 +  return make(_ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id, NULL, _inline_depth);
   3.419 +}
   3.420 +
   3.421 +const TypeOopPtr *TypeInstPtr::with_inline_depth(int depth) const {
   3.422 +  if (!UseInlineDepthForSpeculativeTypes) {
   3.423 +    return this;
   3.424 +  }
   3.425 +  return make(_ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id, _speculative, depth);
   3.426  }
   3.427  
   3.428  //=============================================================================
   3.429 @@ -3591,30 +3681,30 @@
   3.430  const TypeAryPtr *TypeAryPtr::DOUBLES;
   3.431  
   3.432  //------------------------------make-------------------------------------------
   3.433 -const TypeAryPtr *TypeAryPtr::make(PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id, const TypeOopPtr* speculative) {
   3.434 +const TypeAryPtr *TypeAryPtr::make(PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id, const TypeOopPtr* speculative, int inline_depth) {
   3.435    assert(!(k == NULL && ary->_elem->isa_int()),
   3.436           "integral arrays must be pre-equipped with a class");
   3.437    if (!xk)  xk = ary->ary_must_be_exact();
   3.438    assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed");
   3.439    if (!UseExactTypes)  xk = (ptr == Constant);
   3.440 -  return (TypeAryPtr*)(new TypeAryPtr(ptr, NULL, ary, k, xk, offset, instance_id, false, speculative))->hashcons();
   3.441 +  return (TypeAryPtr*)(new TypeAryPtr(ptr, NULL, ary, k, xk, offset, instance_id, false, speculative, inline_depth))->hashcons();
   3.442  }
   3.443  
   3.444  //------------------------------make-------------------------------------------
   3.445 -const TypeAryPtr *TypeAryPtr::make(PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id, const TypeOopPtr* speculative, bool is_autobox_cache) {
   3.446 +const TypeAryPtr *TypeAryPtr::make(PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id, const TypeOopPtr* speculative, int inline_depth, bool is_autobox_cache) {
   3.447    assert(!(k == NULL && ary->_elem->isa_int()),
   3.448           "integral arrays must be pre-equipped with a class");
   3.449    assert( (ptr==Constant && o) || (ptr!=Constant && !o), "" );
   3.450    if (!xk)  xk = (o != NULL) || ary->ary_must_be_exact();
   3.451    assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed");
   3.452    if (!UseExactTypes)  xk = (ptr == Constant);
   3.453 -  return (TypeAryPtr*)(new TypeAryPtr(ptr, o, ary, k, xk, offset, instance_id, is_autobox_cache, speculative))->hashcons();
   3.454 +  return (TypeAryPtr*)(new TypeAryPtr(ptr, o, ary, k, xk, offset, instance_id, is_autobox_cache, speculative, inline_depth))->hashcons();
   3.455  }
   3.456  
   3.457  //------------------------------cast_to_ptr_type-------------------------------
   3.458  const Type *TypeAryPtr::cast_to_ptr_type(PTR ptr) const {
   3.459    if( ptr == _ptr ) return this;
   3.460 -  return make(ptr, const_oop(), _ary, klass(), klass_is_exact(), _offset, _instance_id, _speculative);
   3.461 +  return make(ptr, const_oop(), _ary, klass(), klass_is_exact(), _offset, _instance_id, _speculative, _inline_depth);
   3.462  }
   3.463  
   3.464  
   3.465 @@ -3623,13 +3713,13 @@
   3.466    if( klass_is_exact == _klass_is_exact ) return this;
   3.467    if (!UseExactTypes)  return this;
   3.468    if (_ary->ary_must_be_exact())  return this;  // cannot clear xk
   3.469 -  return make(ptr(), const_oop(), _ary, klass(), klass_is_exact, _offset, _instance_id, _speculative);
   3.470 +  return make(ptr(), const_oop(), _ary, klass(), klass_is_exact, _offset, _instance_id, _speculative, _inline_depth);
   3.471  }
   3.472  
   3.473  //-----------------------------cast_to_instance_id----------------------------
   3.474  const TypeOopPtr *TypeAryPtr::cast_to_instance_id(int instance_id) const {
   3.475    if( instance_id == _instance_id ) return this;
   3.476 -  return make(_ptr, const_oop(), _ary, klass(), _klass_is_exact, _offset, instance_id, _speculative);
   3.477 +  return make(_ptr, const_oop(), _ary, klass(), _klass_is_exact, _offset, instance_id, _speculative, _inline_depth);
   3.478  }
   3.479  
   3.480  //-----------------------------narrow_size_type-------------------------------
   3.481 @@ -3692,7 +3782,7 @@
   3.482    new_size = narrow_size_type(new_size);
   3.483    if (new_size == size())  return this;
   3.484    const TypeAry* new_ary = TypeAry::make(elem(), new_size, is_stable());
   3.485 -  return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id, _speculative);
   3.486 +  return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id, _speculative, _inline_depth);
   3.487  }
   3.488  
   3.489  
   3.490 @@ -3771,19 +3861,20 @@
   3.491      const TypeOopPtr *tp = t->is_oopptr();
   3.492      int offset = meet_offset(tp->offset());
   3.493      PTR ptr = meet_ptr(tp->ptr());
   3.494 +    int depth = meet_inline_depth(tp->inline_depth());
   3.495      switch (tp->ptr()) {
   3.496      case TopPTR:
   3.497      case AnyNull: {
   3.498        int instance_id = meet_instance_id(InstanceTop);
   3.499        const TypeOopPtr* speculative = xmeet_speculative(tp);
   3.500        return make(ptr, (ptr == Constant ? const_oop() : NULL),
   3.501 -                  _ary, _klass, _klass_is_exact, offset, instance_id, speculative);
   3.502 +                  _ary, _klass, _klass_is_exact, offset, instance_id, speculative, depth);
   3.503      }
   3.504      case BotPTR:
   3.505      case NotNull: {
   3.506        int instance_id = meet_instance_id(tp->instance_id());
   3.507        const TypeOopPtr* speculative = xmeet_speculative(tp);
   3.508 -      return TypeOopPtr::make(ptr, offset, instance_id, speculative);
   3.509 +      return TypeOopPtr::make(ptr, offset, instance_id, speculative, depth);
   3.510      }
   3.511      default: ShouldNotReachHere();
   3.512      }
   3.513 @@ -3807,7 +3898,7 @@
   3.514        int instance_id = meet_instance_id(InstanceTop);
   3.515        const TypeOopPtr* speculative = _speculative;
   3.516        return make(ptr, (ptr == Constant ? const_oop() : NULL),
   3.517 -                  _ary, _klass, _klass_is_exact, offset, instance_id, speculative);
   3.518 +                  _ary, _klass, _klass_is_exact, offset, instance_id, speculative, _inline_depth);
   3.519      }
   3.520      default: ShouldNotReachHere();
   3.521      }
   3.522 @@ -3824,6 +3915,7 @@
   3.523      PTR ptr = meet_ptr(tap->ptr());
   3.524      int instance_id = meet_instance_id(tap->instance_id());
   3.525      const TypeOopPtr* speculative = xmeet_speculative(tap);
   3.526 +    int depth = meet_inline_depth(tap->inline_depth());
   3.527      ciKlass* lazy_klass = NULL;
   3.528      if (tary->_elem->isa_int()) {
   3.529        // Integral array element types have irrelevant lattice relations.
   3.530 @@ -3864,7 +3956,7 @@
   3.531        } else {
   3.532          xk = (tap->_klass_is_exact | this->_klass_is_exact);
   3.533        }
   3.534 -      return make(ptr, const_oop(), tary, lazy_klass, xk, off, instance_id, speculative);
   3.535 +      return make(ptr, const_oop(), tary, lazy_klass, xk, off, instance_id, speculative, depth);
   3.536      case Constant: {
   3.537        ciObject* o = const_oop();
   3.538        if( _ptr == Constant ) {
   3.539 @@ -3883,7 +3975,7 @@
   3.540          // Only precise for identical arrays
   3.541          xk = this->_klass_is_exact && (klass() == tap->klass());
   3.542        }
   3.543 -      return TypeAryPtr::make(ptr, o, tary, lazy_klass, xk, off, instance_id, speculative);
   3.544 +      return TypeAryPtr::make(ptr, o, tary, lazy_klass, xk, off, instance_id, speculative, depth);
   3.545      }
   3.546      case NotNull:
   3.547      case BotPTR:
   3.548 @@ -3892,7 +3984,7 @@
   3.549              xk = tap->_klass_is_exact;
   3.550        else  xk = (tap->_klass_is_exact & this->_klass_is_exact) &&
   3.551                (klass() == tap->klass()); // Only precise for identical arrays
   3.552 -      return TypeAryPtr::make(ptr, NULL, tary, lazy_klass, xk, off, instance_id, speculative);
   3.553 +      return TypeAryPtr::make(ptr, NULL, tary, lazy_klass, xk, off, instance_id, speculative, depth);
   3.554      default: ShouldNotReachHere();
   3.555      }
   3.556    }
   3.557 @@ -3904,6 +3996,7 @@
   3.558      PTR ptr = meet_ptr(tp->ptr());
   3.559      int instance_id = meet_instance_id(tp->instance_id());
   3.560      const TypeOopPtr* speculative = xmeet_speculative(tp);
   3.561 +    int depth = meet_inline_depth(tp->inline_depth());
   3.562      switch (ptr) {
   3.563      case TopPTR:
   3.564      case AnyNull:                // Fall 'down' to dual of object klass
   3.565 @@ -3911,12 +4004,12 @@
   3.566        // below the centerline when the superclass is exact. We need to
   3.567        // do the same here.
   3.568        if (tp->klass()->equals(ciEnv::current()->Object_klass()) && !tp->klass_is_exact()) {
   3.569 -        return TypeAryPtr::make(ptr, _ary, _klass, _klass_is_exact, offset, instance_id, speculative);
   3.570 +        return TypeAryPtr::make(ptr, _ary, _klass, _klass_is_exact, offset, instance_id, speculative, depth);
   3.571        } else {
   3.572          // cannot subclass, so the meet has to fall badly below the centerline
   3.573          ptr = NotNull;
   3.574          instance_id = InstanceBot;
   3.575 -        return TypeInstPtr::make(ptr, ciEnv::current()->Object_klass(), false, NULL,offset, instance_id, speculative);
   3.576 +        return TypeInstPtr::make(ptr, ciEnv::current()->Object_klass(), false, NULL,offset, instance_id, speculative, depth);
   3.577        }
   3.578      case Constant:
   3.579      case NotNull:
   3.580 @@ -3931,7 +4024,7 @@
   3.581          if (tp->klass()->equals(ciEnv::current()->Object_klass()) && !tp->klass_is_exact()) {
   3.582            // that is, my array type is a subtype of 'tp' klass
   3.583            return make(ptr, (ptr == Constant ? const_oop() : NULL),
   3.584 -                      _ary, _klass, _klass_is_exact, offset, instance_id, speculative);
   3.585 +                      _ary, _klass, _klass_is_exact, offset, instance_id, speculative, depth);
   3.586          }
   3.587        }
   3.588        // The other case cannot happen, since t cannot be a subtype of an array.
   3.589 @@ -3939,7 +4032,7 @@
   3.590        if( ptr == Constant )
   3.591           ptr = NotNull;
   3.592        instance_id = InstanceBot;
   3.593 -      return TypeInstPtr::make(ptr, ciEnv::current()->Object_klass(), false, NULL,offset, instance_id, speculative);
   3.594 +      return TypeInstPtr::make(ptr, ciEnv::current()->Object_klass(), false, NULL,offset, instance_id, speculative, depth);
   3.595      default: typerr(t);
   3.596      }
   3.597    }
   3.598 @@ -3950,7 +4043,7 @@
   3.599  //------------------------------xdual------------------------------------------
   3.600  // Dual: compute field-by-field dual
   3.601  const Type *TypeAryPtr::xdual() const {
   3.602 -  return new TypeAryPtr(dual_ptr(), _const_oop, _ary->dual()->is_ary(),_klass, _klass_is_exact, dual_offset(), dual_instance_id(), is_autobox_cache(), dual_speculative());
   3.603 +  return new TypeAryPtr(dual_ptr(), _const_oop, _ary->dual()->is_ary(),_klass, _klass_is_exact, dual_offset(), dual_instance_id(), is_autobox_cache(), dual_speculative(), dual_inline_depth());
   3.604  }
   3.605  
   3.606  //----------------------interface_vs_oop---------------------------------------
   3.607 @@ -4003,6 +4096,7 @@
   3.608    else if (_instance_id != InstanceBot)
   3.609      st->print(",iid=%d",_instance_id);
   3.610  
   3.611 +  dump_inline_depth(st);
   3.612    dump_speculative(st);
   3.613  }
   3.614  #endif
   3.615 @@ -4014,11 +4108,22 @@
   3.616  
   3.617  //------------------------------add_offset-------------------------------------
   3.618  const TypePtr *TypeAryPtr::add_offset(intptr_t offset) const {
   3.619 -  return make(_ptr, _const_oop, _ary, _klass, _klass_is_exact, xadd_offset(offset), _instance_id, add_offset_speculative(offset));
   3.620 +  return make(_ptr, _const_oop, _ary, _klass, _klass_is_exact, xadd_offset(offset), _instance_id, add_offset_speculative(offset), _inline_depth);
   3.621  }
   3.622  
   3.623  const Type *TypeAryPtr::remove_speculative() const {
   3.624 -  return make(_ptr, _const_oop, _ary->remove_speculative()->is_ary(), _klass, _klass_is_exact, _offset, _instance_id, NULL);
   3.625 +  if (_speculative == NULL) {
   3.626 +    return this;
   3.627 +  }
   3.628 +  assert(_inline_depth == InlineDepthTop || _inline_depth == InlineDepthBottom, "non speculative type shouldn't have inline depth");
   3.629 +  return make(_ptr, _const_oop, _ary->remove_speculative()->is_ary(), _klass, _klass_is_exact, _offset, _instance_id, NULL, _inline_depth);
   3.630 +}
   3.631 +
   3.632 +const TypeOopPtr *TypeAryPtr::with_inline_depth(int depth) const {
   3.633 +  if (!UseInlineDepthForSpeculativeTypes) {
   3.634 +    return this;
   3.635 +  }
   3.636 +  return make(_ptr, _const_oop, _ary->remove_speculative()->is_ary(), _klass, _klass_is_exact, _offset, _instance_id, _speculative, depth);
   3.637  }
   3.638  
   3.639  //=============================================================================
     4.1 --- a/src/share/vm/opto/type.hpp	Tue Feb 25 18:16:24 2014 +0100
     4.2 +++ b/src/share/vm/opto/type.hpp	Fri Mar 14 17:15:32 2014 +0100
     4.3 @@ -415,10 +415,15 @@
     4.4                                          bool is_autobox_cache = false);
     4.5  
     4.6    // Speculative type. See TypeInstPtr
     4.7 +  virtual const TypeOopPtr* speculative() const { return NULL; }
     4.8    virtual ciKlass* speculative_type() const { return NULL; }
     4.9    const Type* maybe_remove_speculative(bool include_speculative) const;
    4.10    virtual const Type* remove_speculative() const { return this; }
    4.11  
    4.12 +  virtual bool would_improve_type(ciKlass* exact_kls, int inline_depth) const {
    4.13 +    return exact_kls != NULL;
    4.14 +  }
    4.15 +
    4.16  private:
    4.17    // support arrays
    4.18    static const BasicType _basic_type[];
    4.19 @@ -842,7 +847,7 @@
    4.20  // Some kind of oop (Java pointer), either klass or instance or array.
    4.21  class TypeOopPtr : public TypePtr {
    4.22  protected:
    4.23 -  TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id, const TypeOopPtr* speculative);
    4.24 +  TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id, const TypeOopPtr* speculative, int inline_depth);
    4.25  public:
    4.26    virtual bool eq( const Type *t ) const;
    4.27    virtual int  hash() const;             // Type specific hashing
    4.28 @@ -853,6 +858,10 @@
    4.29    };
    4.30  protected:
    4.31  
    4.32 +  enum {
    4.33 +    InlineDepthBottom = INT_MAX,
    4.34 +    InlineDepthTop = -InlineDepthBottom
    4.35 +  };
    4.36    // Oop is NULL, unless this is a constant oop.
    4.37    ciObject*     _const_oop;   // Constant oop
    4.38    // If _klass is NULL, then so is _sig.  This is an unloaded klass.
    4.39 @@ -873,6 +882,11 @@
    4.40    // use it, then we have to emit a guard: this part of the type is
    4.41    // not something we know but something we speculate about the type.
    4.42    const TypeOopPtr*   _speculative;
    4.43 +  // For speculative types, we record at what inlining depth the
    4.44 +  // profiling point that provided the data is. We want to favor
    4.45 +  // profile data coming from outer scopes which are likely better for
    4.46 +  // the current compilation.
    4.47 +  int _inline_depth;
    4.48  
    4.49    static const TypeOopPtr* make_from_klass_common(ciKlass* klass, bool klass_change, bool try_for_exact);
    4.50  
    4.51 @@ -888,6 +902,12 @@
    4.52  #ifndef PRODUCT
    4.53    void dump_speculative(outputStream *st) const;
    4.54  #endif
    4.55 +  // utility methods to work on the inline depth of the type
    4.56 +  int dual_inline_depth() const;
    4.57 +  int meet_inline_depth(int depth) const;
    4.58 +#ifndef PRODUCT
    4.59 +  void dump_inline_depth(outputStream *st) const;
    4.60 +#endif
    4.61  
    4.62    // Do not allow interface-vs.-noninterface joins to collapse to top.
    4.63    virtual const Type *filter_helper(const Type *kills, bool include_speculative) const;
    4.64 @@ -918,7 +938,7 @@
    4.65                                                bool not_null_elements = false);
    4.66  
    4.67    // Make a generic (unclassed) pointer to an oop.
    4.68 -  static const TypeOopPtr* make(PTR ptr, int offset, int instance_id, const TypeOopPtr* speculative);
    4.69 +  static const TypeOopPtr* make(PTR ptr, int offset, int instance_id, const TypeOopPtr* speculative = NULL, int inline_depth = InlineDepthBottom);
    4.70  
    4.71    ciObject* const_oop()    const { return _const_oop; }
    4.72    virtual ciKlass* klass() const { return _klass;     }
    4.73 @@ -932,7 +952,7 @@
    4.74    bool is_known_instance()       const { return _instance_id > 0; }
    4.75    int  instance_id()             const { return _instance_id; }
    4.76    bool is_known_instance_field() const { return is_known_instance() && _offset >= 0; }
    4.77 -  const TypeOopPtr* speculative() const { return _speculative; }
    4.78 +  virtual const TypeOopPtr* speculative() const { return _speculative; }
    4.79  
    4.80    virtual intptr_t get_con() const;
    4.81  
    4.82 @@ -965,18 +985,23 @@
    4.83      if (_speculative != NULL) {
    4.84        const TypeOopPtr* speculative = _speculative->join(this)->is_oopptr();
    4.85        if (speculative->klass_is_exact()) {
    4.86 -       return speculative->klass();
    4.87 +        return speculative->klass();
    4.88        }
    4.89      }
    4.90      return NULL;
    4.91    }
    4.92 +  int inline_depth() const {
    4.93 +    return _inline_depth;
    4.94 +  }
    4.95 +  virtual const TypeOopPtr* with_inline_depth(int depth) const;
    4.96 +  virtual bool would_improve_type(ciKlass* exact_kls, int inline_depth) const;
    4.97  };
    4.98  
    4.99  //------------------------------TypeInstPtr------------------------------------
   4.100  // Class of Java object pointers, pointing either to non-array Java instances
   4.101  // or to a Klass* (including array klasses).
   4.102  class TypeInstPtr : public TypeOopPtr {
   4.103 -  TypeInstPtr(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id, const TypeOopPtr* speculative);
   4.104 +  TypeInstPtr(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id, const TypeOopPtr* speculative, int inline_depth);
   4.105    virtual bool eq( const Type *t ) const;
   4.106    virtual int  hash() const;             // Type specific hashing
   4.107  
   4.108 @@ -1012,7 +1037,7 @@
   4.109    }
   4.110  
   4.111    // Make a pointer to an oop.
   4.112 -  static const TypeInstPtr *make(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id = InstanceBot, const TypeOopPtr* speculative = NULL);
   4.113 +  static const TypeInstPtr *make(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id = InstanceBot, const TypeOopPtr* speculative = NULL, int inline_depth = InlineDepthBottom);
   4.114  
   4.115    /** Create constant type for a constant boxed value */
   4.116    const Type* get_const_boxed_value() const;
   4.117 @@ -1031,6 +1056,7 @@
   4.118    virtual const TypePtr *add_offset( intptr_t offset ) const;
   4.119    // Return same type without a speculative part
   4.120    virtual const Type* remove_speculative() const;
   4.121 +  virtual const TypeOopPtr* with_inline_depth(int depth) const;
   4.122  
   4.123    // the core of the computation of the meet of 2 types
   4.124    virtual const Type *xmeet_helper(const Type *t) const;
   4.125 @@ -1052,8 +1078,8 @@
   4.126  // Class of Java array pointers
   4.127  class TypeAryPtr : public TypeOopPtr {
   4.128    TypeAryPtr( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk,
   4.129 -              int offset, int instance_id, bool is_autobox_cache, const TypeOopPtr* speculative)
   4.130 -    : TypeOopPtr(AryPtr,ptr,k,xk,o,offset, instance_id, speculative),
   4.131 +              int offset, int instance_id, bool is_autobox_cache, const TypeOopPtr* speculative, int inline_depth)
   4.132 +    : TypeOopPtr(AryPtr,ptr,k,xk,o,offset, instance_id, speculative, inline_depth),
   4.133      _ary(ary),
   4.134      _is_autobox_cache(is_autobox_cache)
   4.135   {
   4.136 @@ -1091,9 +1117,9 @@
   4.137  
   4.138    bool is_autobox_cache() const { return _is_autobox_cache; }
   4.139  
   4.140 -  static const TypeAryPtr *make( PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot, const TypeOopPtr* speculative = NULL);
   4.141 +  static const TypeAryPtr *make( PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot, const TypeOopPtr* speculative = NULL, int inline_depth = InlineDepthBottom);
   4.142    // Constant pointer to array
   4.143 -  static const TypeAryPtr *make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot, const TypeOopPtr* speculative = NULL, bool is_autobox_cache = false);
   4.144 +  static const TypeAryPtr *make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot, const TypeOopPtr* speculative = NULL, int inline_depth = InlineDepthBottom, bool is_autobox_cache= false);
   4.145  
   4.146    // Return a 'ptr' version of this type
   4.147    virtual const Type *cast_to_ptr_type(PTR ptr) const;
   4.148 @@ -1109,6 +1135,7 @@
   4.149    virtual const TypePtr *add_offset( intptr_t offset ) const;
   4.150    // Return same type without a speculative part
   4.151    virtual const Type* remove_speculative() const;
   4.152 +  virtual const TypeOopPtr* with_inline_depth(int depth) const;
   4.153  
   4.154    // the core of the computation of the meet of 2 types
   4.155    virtual const Type *xmeet_helper(const Type *t) const;

mercurial