--- a/hotspot/src/share/vm/opto/type.cpp Thu Feb 27 20:40:24 2014 +0100
+++ b/hotspot/src/share/vm/opto/type.cpp Fri Feb 28 13:44:16 2014 +0100
@@ -2463,7 +2463,7 @@
const TypeOopPtr *TypeOopPtr::BOTTOM;
//------------------------------TypeOopPtr-------------------------------------
-TypeOopPtr::TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id, const TypeOopPtr* speculative)
+TypeOopPtr::TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id, const TypeOopPtr* speculative, int inline_depth)
: TypePtr(t, ptr, offset),
_const_oop(o), _klass(k),
_klass_is_exact(xk),
@@ -2471,7 +2471,8 @@
_is_ptr_to_narrowklass(false),
_is_ptr_to_boxed_value(false),
_instance_id(instance_id),
- _speculative(speculative) {
+ _speculative(speculative),
+ _inline_depth(inline_depth){
if (Compile::current()->eliminate_boxing() && (t == InstPtr) &&
(offset > 0) && xk && (k != 0) && k->is_instance_klass()) {
_is_ptr_to_boxed_value = k->as_instance_klass()->is_boxed_value_offset(offset);
@@ -2538,12 +2539,12 @@
//------------------------------make-------------------------------------------
const TypeOopPtr *TypeOopPtr::make(PTR ptr,
- int offset, int instance_id, const TypeOopPtr* speculative) {
+ int offset, int instance_id, const TypeOopPtr* speculative, int inline_depth) {
assert(ptr != Constant, "no constant generic pointers");
ciKlass* k = Compile::current()->env()->Object_klass();
bool xk = false;
ciObject* o = NULL;
- return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, xk, o, offset, instance_id, speculative))->hashcons();
+ return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, xk, o, offset, instance_id, speculative, inline_depth))->hashcons();
}
@@ -2551,7 +2552,7 @@
const Type *TypeOopPtr::cast_to_ptr_type(PTR ptr) const {
assert(_base == OopPtr, "subclass must override cast_to_ptr_type");
if( ptr == _ptr ) return this;
- return make(ptr, _offset, _instance_id, _speculative);
+ return make(ptr, _offset, _instance_id, _speculative, _inline_depth);
}
//-----------------------------cast_to_instance_id----------------------------
@@ -2648,7 +2649,7 @@
case AnyNull: {
int instance_id = meet_instance_id(InstanceTop);
const TypeOopPtr* speculative = _speculative;
- return make(ptr, offset, instance_id, speculative);
+ return make(ptr, offset, instance_id, speculative, _inline_depth);
}
case BotPTR:
case NotNull:
@@ -2661,7 +2662,8 @@
const TypeOopPtr *tp = t->is_oopptr();
int instance_id = meet_instance_id(tp->instance_id());
const TypeOopPtr* speculative = xmeet_speculative(tp);
- return make(meet_ptr(tp->ptr()), meet_offset(tp->offset()), instance_id, speculative);
+ int depth = meet_inline_depth(tp->inline_depth());
+ return make(meet_ptr(tp->ptr()), meet_offset(tp->offset()), instance_id, speculative, depth);
}
case InstPtr: // For these, flip the call around to cut down
@@ -2678,7 +2680,7 @@
const Type *TypeOopPtr::xdual() const {
assert(klass() == Compile::current()->env()->Object_klass(), "no klasses here");
assert(const_oop() == NULL, "no constants here");
- return new TypeOopPtr(_base, dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance_id(), dual_speculative());
+ return new TypeOopPtr(_base, dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance_id(), dual_speculative(), dual_inline_depth());
}
//--------------------------make_from_klass_common-----------------------------
@@ -2769,7 +2771,7 @@
} else if (!o->should_be_constant()) {
return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0);
}
- const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0, InstanceBot, NULL, is_autobox_cache);
+ const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0, InstanceBot, NULL, InlineDepthBottom, is_autobox_cache);
return arr;
} else if (klass->is_type_array_klass()) {
// Element is an typeArray
@@ -2858,7 +2860,8 @@
const TypeOopPtr *a = (const TypeOopPtr*)t;
if (_klass_is_exact != a->_klass_is_exact ||
_instance_id != a->_instance_id ||
- !eq_speculative(a)) return false;
+ !eq_speculative(a) ||
+ _inline_depth != a->_inline_depth) return false;
ciObject* one = const_oop();
ciObject* two = a->const_oop();
if (one == NULL || two == NULL) {
@@ -2876,6 +2879,7 @@
_klass_is_exact +
_instance_id +
hash_speculative() +
+ _inline_depth +
TypePtr::hash();
}
@@ -2896,6 +2900,7 @@
else if (_instance_id != InstanceBot)
st->print(",iid=%d",_instance_id);
+ dump_inline_depth(st);
dump_speculative(st);
}
@@ -2909,6 +2914,16 @@
st->print(")");
}
}
+
+void TypeOopPtr::dump_inline_depth(outputStream *st) const {
+ if (_inline_depth != InlineDepthBottom) {
+ if (_inline_depth == InlineDepthTop) {
+ st->print(" (inline_depth=InlineDepthTop)");
+ } else {
+ st->print(" (inline_depth=%d)", _inline_depth);
+ }
+ }
+}
#endif
//------------------------------singleton--------------------------------------
@@ -2922,7 +2937,7 @@
//------------------------------add_offset-------------------------------------
const TypePtr *TypeOopPtr::add_offset(intptr_t offset) const {
- return make(_ptr, xadd_offset(offset), _instance_id, add_offset_speculative(offset));
+ return make(_ptr, xadd_offset(offset), _instance_id, add_offset_speculative(offset), _inline_depth);
}
/**
@@ -2932,7 +2947,52 @@
if (_speculative == NULL) {
return this;
}
- return make(_ptr, _offset, _instance_id, NULL);
+ assert(_inline_depth == InlineDepthTop || _inline_depth == InlineDepthBottom, "non speculative type shouldn't have inline depth");
+ return make(_ptr, _offset, _instance_id, NULL, _inline_depth);
+}
+
+/**
+ * Return same type but with a different inline depth (used for speculation)
+ *
+ * @param depth depth to meet with
+ */
+const TypeOopPtr* TypeOopPtr::with_inline_depth(int depth) const {
+ if (!UseInlineDepthForSpeculativeTypes) {
+ return this;
+ }
+ return make(_ptr, _offset, _instance_id, _speculative, depth);
+}
+
+/**
+ * Check whether new profiling would improve speculative type
+ *
+ * @param exact_kls class from profiling
+ * @param inline_depth inlining depth of profile point
+ *
+ * @return true if type profile is valuable
+ */
+bool TypeOopPtr::would_improve_type(ciKlass* exact_kls, int inline_depth) const {
+ // no way to improve an already exact type
+ if (klass_is_exact()) {
+ return false;
+ }
+ // no profiling?
+ if (exact_kls == NULL) {
+ return false;
+ }
+ // no speculative type or non exact speculative type?
+ if (speculative_type() == NULL) {
+ return true;
+ }
+ // If the node already has an exact speculative type keep it,
+ // unless it was provided by profiling that is at a deeper
+ // inlining level. Profiling at a higher inlining depth is
+ // expected to be less accurate.
+ if (_speculative->inline_depth() == InlineDepthBottom) {
+ return false;
+ }
+ assert(_speculative->inline_depth() != InlineDepthTop, "can't do the comparison");
+ return inline_depth < _speculative->inline_depth();
}
//------------------------------meet_instance_id--------------------------------
@@ -3035,6 +3095,21 @@
return _speculative->hash();
}
+/**
+ * dual of the inline depth for this type (used for speculation)
+ */
+int TypeOopPtr::dual_inline_depth() const {
+ return -inline_depth();
+}
+
+/**
+ * meet of 2 inline depth (used for speculation)
+ *
+ * @param depth depth to meet with
+ */
+int TypeOopPtr::meet_inline_depth(int depth) const {
+ return MAX2(inline_depth(), depth);
+}
//=============================================================================
// Convenience common pre-built types.
@@ -3045,8 +3120,8 @@
const TypeInstPtr *TypeInstPtr::KLASS;
//------------------------------TypeInstPtr-------------------------------------
-TypeInstPtr::TypeInstPtr(PTR ptr, ciKlass* k, bool xk, ciObject* o, int off, int instance_id, const TypeOopPtr* speculative)
- : TypeOopPtr(InstPtr, ptr, k, xk, o, off, instance_id, speculative), _name(k->name()) {
+TypeInstPtr::TypeInstPtr(PTR ptr, ciKlass* k, bool xk, ciObject* o, int off, int instance_id, const TypeOopPtr* speculative, int inline_depth)
+ : TypeOopPtr(InstPtr, ptr, k, xk, o, off, instance_id, speculative, inline_depth), _name(k->name()) {
assert(k != NULL &&
(k->is_loaded() || o == NULL),
"cannot have constants with non-loaded klass");
@@ -3059,7 +3134,8 @@
ciObject* o,
int offset,
int instance_id,
- const TypeOopPtr* speculative) {
+ const TypeOopPtr* speculative,
+ int inline_depth) {
assert( !k->is_loaded() || k->is_instance_klass(), "Must be for instance");
// Either const_oop() is NULL or else ptr is Constant
assert( (!o && ptr != Constant) || (o && ptr == Constant),
@@ -3080,7 +3156,7 @@
// Now hash this baby
TypeInstPtr *result =
- (TypeInstPtr*)(new TypeInstPtr(ptr, k, xk, o ,offset, instance_id, speculative))->hashcons();
+ (TypeInstPtr*)(new TypeInstPtr(ptr, k, xk, o ,offset, instance_id, speculative, inline_depth))->hashcons();
return result;
}
@@ -3113,7 +3189,7 @@
if( ptr == _ptr ) return this;
// Reconstruct _sig info here since not a problem with later lazy
// construction, _sig will show up on demand.
- return make(ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id, _speculative);
+ return make(ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id, _speculative, _inline_depth);
}
@@ -3125,13 +3201,13 @@
ciInstanceKlass* ik = _klass->as_instance_klass();
if( (ik->is_final() || _const_oop) ) return this; // cannot clear xk
if( ik->is_interface() ) return this; // cannot set xk
- return make(ptr(), klass(), klass_is_exact, const_oop(), _offset, _instance_id, _speculative);
+ return make(ptr(), klass(), klass_is_exact, const_oop(), _offset, _instance_id, _speculative, _inline_depth);
}
//-----------------------------cast_to_instance_id----------------------------
const TypeOopPtr *TypeInstPtr::cast_to_instance_id(int instance_id) const {
if( instance_id == _instance_id ) return this;
- return make(_ptr, klass(), _klass_is_exact, const_oop(), _offset, instance_id, _speculative);
+ return make(_ptr, klass(), _klass_is_exact, const_oop(), _offset, instance_id, _speculative, _inline_depth);
}
//------------------------------xmeet_unloaded---------------------------------
@@ -3142,6 +3218,7 @@
PTR ptr = meet_ptr(tinst->ptr());
int instance_id = meet_instance_id(tinst->instance_id());
const TypeOopPtr* speculative = xmeet_speculative(tinst);
+ int depth = meet_inline_depth(tinst->inline_depth());
const TypeInstPtr *loaded = is_loaded() ? this : tinst;
const TypeInstPtr *unloaded = is_loaded() ? tinst : this;
@@ -3162,7 +3239,7 @@
assert(loaded->ptr() != TypePtr::Null, "insanity check");
//
if( loaded->ptr() == TypePtr::TopPTR ) { return unloaded; }
- else if (loaded->ptr() == TypePtr::AnyNull) { return TypeInstPtr::make(ptr, unloaded->klass(), false, NULL, off, instance_id, speculative); }
+ else if (loaded->ptr() == TypePtr::AnyNull) { return TypeInstPtr::make(ptr, unloaded->klass(), false, NULL, off, instance_id, speculative, depth); }
else if (loaded->ptr() == TypePtr::BotPTR ) { return TypeInstPtr::BOTTOM; }
else if (loaded->ptr() == TypePtr::Constant || loaded->ptr() == TypePtr::NotNull) {
if (unloaded->ptr() == TypePtr::BotPTR ) { return TypeInstPtr::BOTTOM; }
@@ -3219,6 +3296,7 @@
PTR ptr = meet_ptr(tp->ptr());
int instance_id = meet_instance_id(tp->instance_id());
const TypeOopPtr* speculative = xmeet_speculative(tp);
+ int depth = meet_inline_depth(tp->inline_depth());
switch (ptr) {
case TopPTR:
case AnyNull: // Fall 'down' to dual of object klass
@@ -3226,12 +3304,12 @@
// below the centerline when the superclass is exact. We need to
// do the same here.
if (klass()->equals(ciEnv::current()->Object_klass()) && !klass_is_exact()) {
- return TypeAryPtr::make(ptr, tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id, speculative);
+ return TypeAryPtr::make(ptr, tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id, speculative, depth);
} else {
// cannot subclass, so the meet has to fall badly below the centerline
ptr = NotNull;
instance_id = InstanceBot;
- return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL, offset, instance_id, speculative);
+ return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL, offset, instance_id, speculative, depth);
}
case Constant:
case NotNull:
@@ -3246,7 +3324,7 @@
if (klass()->equals(ciEnv::current()->Object_klass()) && !klass_is_exact()) {
// that is, tp's array type is a subtype of my klass
return TypeAryPtr::make(ptr, (ptr == Constant ? tp->const_oop() : NULL),
- tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id, speculative);
+ tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id, speculative, depth);
}
}
// The other case cannot happen, since I cannot be a subtype of an array.
@@ -3254,7 +3332,7 @@
if( ptr == Constant )
ptr = NotNull;
instance_id = InstanceBot;
- return make(ptr, ciEnv::current()->Object_klass(), false, NULL, offset, instance_id, speculative);
+ return make(ptr, ciEnv::current()->Object_klass(), false, NULL, offset, instance_id, speculative, depth);
default: typerr(t);
}
}
@@ -3269,14 +3347,16 @@
case AnyNull: {
int instance_id = meet_instance_id(InstanceTop);
const TypeOopPtr* speculative = xmeet_speculative(tp);
+ int depth = meet_inline_depth(tp->inline_depth());
return make(ptr, klass(), klass_is_exact(),
- (ptr == Constant ? const_oop() : NULL), offset, instance_id, speculative);
+ (ptr == Constant ? const_oop() : NULL), offset, instance_id, speculative, depth);
}
case NotNull:
case BotPTR: {
int instance_id = meet_instance_id(tp->instance_id());
const TypeOopPtr* speculative = xmeet_speculative(tp);
- return TypeOopPtr::make(ptr, offset, instance_id, speculative);
+ int depth = meet_inline_depth(tp->inline_depth());
+ return TypeOopPtr::make(ptr, offset, instance_id, speculative, depth);
}
default: typerr(t);
}
@@ -3296,7 +3376,7 @@
int instance_id = meet_instance_id(InstanceTop);
const TypeOopPtr* speculative = _speculative;
return make(ptr, klass(), klass_is_exact(),
- (ptr == Constant ? const_oop() : NULL), offset, instance_id, speculative);
+ (ptr == Constant ? const_oop() : NULL), offset, instance_id, speculative, _inline_depth);
}
case NotNull:
case BotPTR:
@@ -3328,13 +3408,14 @@
PTR ptr = meet_ptr( tinst->ptr() );
int instance_id = meet_instance_id(tinst->instance_id());
const TypeOopPtr* speculative = xmeet_speculative(tinst);
+ int depth = meet_inline_depth(tinst->inline_depth());
// Check for easy case; klasses are equal (and perhaps not loaded!)
// If we have constants, then we created oops so classes are loaded
// and we can handle the constants further down. This case handles
// both-not-loaded or both-loaded classes
if (ptr != Constant && klass()->equals(tinst->klass()) && klass_is_exact() == tinst->klass_is_exact()) {
- return make(ptr, klass(), klass_is_exact(), NULL, off, instance_id, speculative);
+ return make(ptr, klass(), klass_is_exact(), NULL, off, instance_id, speculative, depth);
}
// Classes require inspection in the Java klass hierarchy. Must be loaded.
@@ -3398,7 +3479,7 @@
// Find out which constant.
o = (this_klass == klass()) ? const_oop() : tinst->const_oop();
}
- return make(ptr, k, xk, o, off, instance_id, speculative);
+ return make(ptr, k, xk, o, off, instance_id, speculative, depth);
}
// Either oop vs oop or interface vs interface or interface vs Object
@@ -3475,7 +3556,7 @@
else
ptr = NotNull;
}
- return make(ptr, this_klass, this_xk, o, off, instance_id, speculative);
+ return make(ptr, this_klass, this_xk, o, off, instance_id, speculative, depth);
} // Else classes are not equal
// Since klasses are different, we require a LCA in the Java
@@ -3486,7 +3567,7 @@
// Now we find the LCA of Java classes
ciKlass* k = this_klass->least_common_ancestor(tinst_klass);
- return make(ptr, k, false, NULL, off, instance_id, speculative);
+ return make(ptr, k, false, NULL, off, instance_id, speculative, depth);
} // End of case InstPtr
} // End of switch
@@ -3510,7 +3591,7 @@
// Dual: do NOT dual on klasses. This means I do NOT understand the Java
// inheritance mechanism.
const Type *TypeInstPtr::xdual() const {
- return new TypeInstPtr(dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance_id(), dual_speculative());
+ return new TypeInstPtr(dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance_id(), dual_speculative(), dual_inline_depth());
}
//------------------------------eq---------------------------------------------
@@ -3567,6 +3648,7 @@
else if (_instance_id != InstanceBot)
st->print(",iid=%d",_instance_id);
+ dump_inline_depth(st);
dump_speculative(st);
}
#endif
@@ -3580,7 +3662,15 @@
if (_speculative == NULL) {
return this;
}
- return make(_ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id, NULL);
+ assert(_inline_depth == InlineDepthTop || _inline_depth == InlineDepthBottom, "non speculative type shouldn't have inline depth");
+ return make(_ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id, NULL, _inline_depth);
+}
+
+const TypeOopPtr *TypeInstPtr::with_inline_depth(int depth) const {
+ if (!UseInlineDepthForSpeculativeTypes) {
+ return this;
+ }
+ return make(_ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id, _speculative, depth);
}
//=============================================================================
@@ -3597,30 +3687,30 @@
const TypeAryPtr *TypeAryPtr::DOUBLES;
//------------------------------make-------------------------------------------
-const TypeAryPtr *TypeAryPtr::make(PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id, const TypeOopPtr* speculative) {
+const TypeAryPtr *TypeAryPtr::make(PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id, const TypeOopPtr* speculative, int inline_depth) {
assert(!(k == NULL && ary->_elem->isa_int()),
"integral arrays must be pre-equipped with a class");
if (!xk) xk = ary->ary_must_be_exact();
assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed");
if (!UseExactTypes) xk = (ptr == Constant);
- return (TypeAryPtr*)(new TypeAryPtr(ptr, NULL, ary, k, xk, offset, instance_id, false, speculative))->hashcons();
+ return (TypeAryPtr*)(new TypeAryPtr(ptr, NULL, ary, k, xk, offset, instance_id, false, speculative, inline_depth))->hashcons();
}
//------------------------------make-------------------------------------------
-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) {
+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) {
assert(!(k == NULL && ary->_elem->isa_int()),
"integral arrays must be pre-equipped with a class");
assert( (ptr==Constant && o) || (ptr!=Constant && !o), "" );
if (!xk) xk = (o != NULL) || ary->ary_must_be_exact();
assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed");
if (!UseExactTypes) xk = (ptr == Constant);
- return (TypeAryPtr*)(new TypeAryPtr(ptr, o, ary, k, xk, offset, instance_id, is_autobox_cache, speculative))->hashcons();
+ return (TypeAryPtr*)(new TypeAryPtr(ptr, o, ary, k, xk, offset, instance_id, is_autobox_cache, speculative, inline_depth))->hashcons();
}
//------------------------------cast_to_ptr_type-------------------------------
const Type *TypeAryPtr::cast_to_ptr_type(PTR ptr) const {
if( ptr == _ptr ) return this;
- return make(ptr, const_oop(), _ary, klass(), klass_is_exact(), _offset, _instance_id, _speculative);
+ return make(ptr, const_oop(), _ary, klass(), klass_is_exact(), _offset, _instance_id, _speculative, _inline_depth);
}
@@ -3629,13 +3719,13 @@
if( klass_is_exact == _klass_is_exact ) return this;
if (!UseExactTypes) return this;
if (_ary->ary_must_be_exact()) return this; // cannot clear xk
- return make(ptr(), const_oop(), _ary, klass(), klass_is_exact, _offset, _instance_id, _speculative);
+ return make(ptr(), const_oop(), _ary, klass(), klass_is_exact, _offset, _instance_id, _speculative, _inline_depth);
}
//-----------------------------cast_to_instance_id----------------------------
const TypeOopPtr *TypeAryPtr::cast_to_instance_id(int instance_id) const {
if( instance_id == _instance_id ) return this;
- return make(_ptr, const_oop(), _ary, klass(), _klass_is_exact, _offset, instance_id, _speculative);
+ return make(_ptr, const_oop(), _ary, klass(), _klass_is_exact, _offset, instance_id, _speculative, _inline_depth);
}
//-----------------------------narrow_size_type-------------------------------
@@ -3698,7 +3788,7 @@
new_size = narrow_size_type(new_size);
if (new_size == size()) return this;
const TypeAry* new_ary = TypeAry::make(elem(), new_size, is_stable());
- return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id, _speculative);
+ return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id, _speculative, _inline_depth);
}
@@ -3777,19 +3867,20 @@
const TypeOopPtr *tp = t->is_oopptr();
int offset = meet_offset(tp->offset());
PTR ptr = meet_ptr(tp->ptr());
+ int depth = meet_inline_depth(tp->inline_depth());
switch (tp->ptr()) {
case TopPTR:
case AnyNull: {
int instance_id = meet_instance_id(InstanceTop);
const TypeOopPtr* speculative = xmeet_speculative(tp);
return make(ptr, (ptr == Constant ? const_oop() : NULL),
- _ary, _klass, _klass_is_exact, offset, instance_id, speculative);
+ _ary, _klass, _klass_is_exact, offset, instance_id, speculative, depth);
}
case BotPTR:
case NotNull: {
int instance_id = meet_instance_id(tp->instance_id());
const TypeOopPtr* speculative = xmeet_speculative(tp);
- return TypeOopPtr::make(ptr, offset, instance_id, speculative);
+ return TypeOopPtr::make(ptr, offset, instance_id, speculative, depth);
}
default: ShouldNotReachHere();
}
@@ -3813,7 +3904,7 @@
int instance_id = meet_instance_id(InstanceTop);
const TypeOopPtr* speculative = _speculative;
return make(ptr, (ptr == Constant ? const_oop() : NULL),
- _ary, _klass, _klass_is_exact, offset, instance_id, speculative);
+ _ary, _klass, _klass_is_exact, offset, instance_id, speculative, _inline_depth);
}
default: ShouldNotReachHere();
}
@@ -3830,6 +3921,7 @@
PTR ptr = meet_ptr(tap->ptr());
int instance_id = meet_instance_id(tap->instance_id());
const TypeOopPtr* speculative = xmeet_speculative(tap);
+ int depth = meet_inline_depth(tap->inline_depth());
ciKlass* lazy_klass = NULL;
if (tary->_elem->isa_int()) {
// Integral array element types have irrelevant lattice relations.
@@ -3870,7 +3962,7 @@
} else {
xk = (tap->_klass_is_exact | this->_klass_is_exact);
}
- return make(ptr, const_oop(), tary, lazy_klass, xk, off, instance_id, speculative);
+ return make(ptr, const_oop(), tary, lazy_klass, xk, off, instance_id, speculative, depth);
case Constant: {
ciObject* o = const_oop();
if( _ptr == Constant ) {
@@ -3889,7 +3981,7 @@
// Only precise for identical arrays
xk = this->_klass_is_exact && (klass() == tap->klass());
}
- return TypeAryPtr::make(ptr, o, tary, lazy_klass, xk, off, instance_id, speculative);
+ return TypeAryPtr::make(ptr, o, tary, lazy_klass, xk, off, instance_id, speculative, depth);
}
case NotNull:
case BotPTR:
@@ -3898,7 +3990,7 @@
xk = tap->_klass_is_exact;
else xk = (tap->_klass_is_exact & this->_klass_is_exact) &&
(klass() == tap->klass()); // Only precise for identical arrays
- return TypeAryPtr::make(ptr, NULL, tary, lazy_klass, xk, off, instance_id, speculative);
+ return TypeAryPtr::make(ptr, NULL, tary, lazy_klass, xk, off, instance_id, speculative, depth);
default: ShouldNotReachHere();
}
}
@@ -3910,6 +4002,7 @@
PTR ptr = meet_ptr(tp->ptr());
int instance_id = meet_instance_id(tp->instance_id());
const TypeOopPtr* speculative = xmeet_speculative(tp);
+ int depth = meet_inline_depth(tp->inline_depth());
switch (ptr) {
case TopPTR:
case AnyNull: // Fall 'down' to dual of object klass
@@ -3917,12 +4010,12 @@
// below the centerline when the superclass is exact. We need to
// do the same here.
if (tp->klass()->equals(ciEnv::current()->Object_klass()) && !tp->klass_is_exact()) {
- return TypeAryPtr::make(ptr, _ary, _klass, _klass_is_exact, offset, instance_id, speculative);
+ return TypeAryPtr::make(ptr, _ary, _klass, _klass_is_exact, offset, instance_id, speculative, depth);
} else {
// cannot subclass, so the meet has to fall badly below the centerline
ptr = NotNull;
instance_id = InstanceBot;
- return TypeInstPtr::make(ptr, ciEnv::current()->Object_klass(), false, NULL,offset, instance_id, speculative);
+ return TypeInstPtr::make(ptr, ciEnv::current()->Object_klass(), false, NULL,offset, instance_id, speculative, depth);
}
case Constant:
case NotNull:
@@ -3937,7 +4030,7 @@
if (tp->klass()->equals(ciEnv::current()->Object_klass()) && !tp->klass_is_exact()) {
// that is, my array type is a subtype of 'tp' klass
return make(ptr, (ptr == Constant ? const_oop() : NULL),
- _ary, _klass, _klass_is_exact, offset, instance_id, speculative);
+ _ary, _klass, _klass_is_exact, offset, instance_id, speculative, depth);
}
}
// The other case cannot happen, since t cannot be a subtype of an array.
@@ -3945,7 +4038,7 @@
if( ptr == Constant )
ptr = NotNull;
instance_id = InstanceBot;
- return TypeInstPtr::make(ptr, ciEnv::current()->Object_klass(), false, NULL,offset, instance_id, speculative);
+ return TypeInstPtr::make(ptr, ciEnv::current()->Object_klass(), false, NULL,offset, instance_id, speculative, depth);
default: typerr(t);
}
}
@@ -3956,7 +4049,7 @@
//------------------------------xdual------------------------------------------
// Dual: compute field-by-field dual
const Type *TypeAryPtr::xdual() const {
- 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());
+ 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());
}
//----------------------interface_vs_oop---------------------------------------
@@ -4009,6 +4102,7 @@
else if (_instance_id != InstanceBot)
st->print(",iid=%d",_instance_id);
+ dump_inline_depth(st);
dump_speculative(st);
}
#endif
@@ -4020,11 +4114,22 @@
//------------------------------add_offset-------------------------------------
const TypePtr *TypeAryPtr::add_offset(intptr_t offset) const {
- return make(_ptr, _const_oop, _ary, _klass, _klass_is_exact, xadd_offset(offset), _instance_id, add_offset_speculative(offset));
+ return make(_ptr, _const_oop, _ary, _klass, _klass_is_exact, xadd_offset(offset), _instance_id, add_offset_speculative(offset), _inline_depth);
}
const Type *TypeAryPtr::remove_speculative() const {
- return make(_ptr, _const_oop, _ary->remove_speculative()->is_ary(), _klass, _klass_is_exact, _offset, _instance_id, NULL);
+ if (_speculative == NULL) {
+ return this;
+ }
+ assert(_inline_depth == InlineDepthTop || _inline_depth == InlineDepthBottom, "non speculative type shouldn't have inline depth");
+ return make(_ptr, _const_oop, _ary->remove_speculative()->is_ary(), _klass, _klass_is_exact, _offset, _instance_id, NULL, _inline_depth);
+}
+
+const TypeOopPtr *TypeAryPtr::with_inline_depth(int depth) const {
+ if (!UseInlineDepthForSpeculativeTypes) {
+ return this;
+ }
+ return make(_ptr, _const_oop, _ary->remove_speculative()->is_ary(), _klass, _klass_is_exact, _offset, _instance_id, _speculative, depth);
}
//=============================================================================