Fri, 14 Mar 2014 17:15:32 +0100
8031754: Type speculation should favor profile data from outermost inlined method
Summary: favor profile data coming from outer most method
Reviewed-by: kvn, twisti
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;