src/share/vm/opto/type.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Cdiff src/share/vm/opto/type.cpp

src/share/vm/opto/type.cpp

Print this page
rev 6139 : 8031755: Type speculation should be used to optimize explicit null checks
Summary: feed profiling data about reference nullness to type speculation.
Reviewed-by:

*** 348,360 **** const Type **floop =(const Type**)shared_type_arena->Amalloc_4(2*sizeof(Type*)); floop[0] = Type::CONTROL; floop[1] = TypeInt::INT; TypeTuple::LOOPBODY = TypeTuple::make( 2, floop ); ! TypePtr::NULL_PTR= TypePtr::make( AnyPtr, TypePtr::Null, 0 ); ! TypePtr::NOTNULL = TypePtr::make( AnyPtr, TypePtr::NotNull, OffsetBot ); ! TypePtr::BOTTOM = TypePtr::make( AnyPtr, TypePtr::BotPTR, OffsetBot ); TypeRawPtr::BOTTOM = TypeRawPtr::make( TypePtr::BotPTR ); TypeRawPtr::NOTNULL= TypeRawPtr::make( TypePtr::NotNull ); const Type **fmembar = TypeTuple::fields(0); --- 348,360 ---- const Type **floop =(const Type**)shared_type_arena->Amalloc_4(2*sizeof(Type*)); floop[0] = Type::CONTROL; floop[1] = TypeInt::INT; TypeTuple::LOOPBODY = TypeTuple::make( 2, floop ); ! TypePtr::NULL_PTR= TypePtr::make(AnyPtr, TypePtr::Null, 0); ! TypePtr::NOTNULL = TypePtr::make(AnyPtr, TypePtr::NotNull, OffsetBot); ! TypePtr::BOTTOM = TypePtr::make(AnyPtr, TypePtr::BotPTR, OffsetBot); TypeRawPtr::BOTTOM = TypeRawPtr::make( TypePtr::BotPTR ); TypeRawPtr::NOTNULL= TypeRawPtr::make( TypePtr::NotNull ); const Type **fmembar = TypeTuple::fields(0);
*** 370,380 **** TypeInstPtr::MIRROR = TypeInstPtr::make(TypePtr::NotNull, current->env()->Class_klass()); TypeInstPtr::MARK = TypeInstPtr::make(TypePtr::BotPTR, current->env()->Object_klass(), false, 0, oopDesc::mark_offset_in_bytes()); TypeInstPtr::KLASS = TypeInstPtr::make(TypePtr::BotPTR, current->env()->Object_klass(), false, 0, oopDesc::klass_offset_in_bytes()); ! TypeOopPtr::BOTTOM = TypeOopPtr::make(TypePtr::BotPTR, OffsetBot, TypeOopPtr::InstanceBot, NULL); TypeMetadataPtr::BOTTOM = TypeMetadataPtr::make(TypePtr::BotPTR, NULL, OffsetBot); TypeNarrowOop::NULL_PTR = TypeNarrowOop::make( TypePtr::NULL_PTR ); TypeNarrowOop::BOTTOM = TypeNarrowOop::make( TypeInstPtr::BOTTOM ); --- 370,380 ---- TypeInstPtr::MIRROR = TypeInstPtr::make(TypePtr::NotNull, current->env()->Class_klass()); TypeInstPtr::MARK = TypeInstPtr::make(TypePtr::BotPTR, current->env()->Object_klass(), false, 0, oopDesc::mark_offset_in_bytes()); TypeInstPtr::KLASS = TypeInstPtr::make(TypePtr::BotPTR, current->env()->Object_klass(), false, 0, oopDesc::klass_offset_in_bytes()); ! TypeOopPtr::BOTTOM = TypeOopPtr::make(TypePtr::BotPTR, OffsetBot, TypeOopPtr::InstanceBot); TypeMetadataPtr::BOTTOM = TypeMetadataPtr::make(TypePtr::BotPTR, NULL, OffsetBot); TypeNarrowOop::NULL_PTR = TypeNarrowOop::make( TypePtr::NULL_PTR ); TypeNarrowOop::BOTTOM = TypeNarrowOop::make( TypeInstPtr::BOTTOM );
*** 618,629 **** bool Type::interface_vs_oop(const Type *t) const { if (interface_vs_oop_helper(t)) { return true; } // Now check the speculative parts as well ! const TypeOopPtr* this_spec = isa_oopptr() != NULL ? isa_oopptr()->speculative() : NULL; ! const TypeOopPtr* t_spec = t->isa_oopptr() != NULL ? t->isa_oopptr()->speculative() : NULL; if (this_spec != NULL && t_spec != NULL) { if (this_spec->interface_vs_oop_helper(t_spec)) { return true; } return false; --- 618,629 ---- bool Type::interface_vs_oop(const Type *t) const { if (interface_vs_oop_helper(t)) { return true; } // Now check the speculative parts as well ! const TypePtr* this_spec = isa_ptr() != NULL ? is_ptr()->speculative() : NULL; ! const TypePtr* t_spec = t->isa_ptr() != NULL ? t->is_ptr()->speculative() : NULL; if (this_spec != NULL && t_spec != NULL) { if (this_spec->interface_vs_oop_helper(t_spec)) { return true; } return false;
*** 1973,1982 **** --- 1973,2001 ---- */ const Type* TypeAry::remove_speculative() const { return make(_elem->remove_speculative(), _size, _stable); } + /** + * Return same type with cleaned up speculative part of element + */ + const Type* TypeAry::cleanup_speculative() const { + return make(_elem->cleanup_speculative(), _size, _stable); + } + + /** + * Return same type but with a different inline depth (used for speculation) + * + * @param depth depth to meet with + */ + const TypePtr* TypePtr::with_inline_depth(int depth) const { + if (!UseInlineDepthForSpeculativeTypes) { + return this; + } + return make(AnyPtr, _ptr, _offset, _speculative, depth); + } + //----------------------interface_vs_oop--------------------------------------- #ifdef ASSERT bool TypeAry::interface_vs_oop(const Type *t) const { const TypeAry* t_ary = t->is_ary(); if (t_ary) {
*** 2177,2206 **** { /* NotNull */ NotNull, NotNull, NotNull, BotPTR, NotNull, BotPTR,}, { /* BotPTR */ BotPTR, BotPTR, BotPTR, BotPTR, BotPTR, BotPTR,} }; //------------------------------make------------------------------------------- ! const TypePtr *TypePtr::make( TYPES t, enum PTR ptr, int offset ) { ! return (TypePtr*)(new TypePtr(t,ptr,offset))->hashcons(); } //------------------------------cast_to_ptr_type------------------------------- const Type *TypePtr::cast_to_ptr_type(PTR ptr) const { assert(_base == AnyPtr, "subclass must override cast_to_ptr_type"); if( ptr == _ptr ) return this; ! return make(_base, ptr, _offset); } //------------------------------get_con---------------------------------------- intptr_t TypePtr::get_con() const { assert( _ptr == Null, "" ); return _offset; } //------------------------------meet------------------------------------------- // Compute the MEET of two types. It returns a new Type object. ! const Type *TypePtr::xmeet( const Type *t ) const { // Perform a fast test for common case; meeting the same types together. if( this == t ) return this; // Meeting same type-rep? // Current "this->_base" is AnyPtr switch (t->base()) { // switch on original type --- 2196,2247 ---- { /* NotNull */ NotNull, NotNull, NotNull, BotPTR, NotNull, BotPTR,}, { /* BotPTR */ BotPTR, BotPTR, BotPTR, BotPTR, BotPTR, BotPTR,} }; //------------------------------make------------------------------------------- ! const TypePtr *TypePtr::make(TYPES t, enum PTR ptr, int offset, const TypePtr* speculative, int inline_depth) { ! return (TypePtr*)(new TypePtr(t,ptr,offset, speculative, inline_depth))->hashcons(); } //------------------------------cast_to_ptr_type------------------------------- const Type *TypePtr::cast_to_ptr_type(PTR ptr) const { assert(_base == AnyPtr, "subclass must override cast_to_ptr_type"); if( ptr == _ptr ) return this; ! return make(_base, ptr, _offset, _speculative, _inline_depth); } //------------------------------get_con---------------------------------------- intptr_t TypePtr::get_con() const { assert( _ptr == Null, "" ); return _offset; } //------------------------------meet------------------------------------------- // Compute the MEET of two types. It returns a new Type object. ! const Type *TypePtr::xmeet(const Type *t) const { ! const Type* res = xmeet_helper(t); ! if (res->isa_ptr() == NULL) { ! return res; ! } ! ! const TypePtr* res_ptr = res->is_ptr(); ! if (res_ptr->speculative() != NULL) { ! // type->speculative() == NULL means that speculation is no better ! // than type, i.e. type->speculative() == type. So there are 2 ! // ways to represent the fact that we have no useful speculative ! // data and we should use a single one to be able to test for ! // equality between types. Check whether type->speculative() == ! // type and set speculative to NULL if it is the case. ! if (res_ptr->remove_speculative() == res_ptr->speculative()) { ! return res_ptr->remove_speculative(); ! } ! } ! ! return res; ! } ! ! const Type *TypePtr::xmeet_helper(const Type *t) const { // Perform a fast test for common case; meeting the same types together. if( this == t ) return this; // Meeting same type-rep? // Current "this->_base" is AnyPtr switch (t->base()) { // switch on original type
*** 2219,2229 **** case Top: return this; case AnyPtr: { // Meeting to AnyPtrs const TypePtr *tp = t->is_ptr(); ! return make( AnyPtr, meet_ptr(tp->ptr()), meet_offset(tp->offset()) ); } case RawPtr: // For these, flip the call around to cut down case OopPtr: case InstPtr: // on the cases I have to handle. case AryPtr: --- 2260,2272 ---- case Top: return this; case AnyPtr: { // Meeting to AnyPtrs const TypePtr *tp = t->is_ptr(); ! const TypePtr* speculative = xmeet_speculative(tp); ! int depth = meet_inline_depth(tp->inline_depth()); ! return make(AnyPtr, meet_ptr(tp->ptr()), meet_offset(tp->offset()), speculative, depth); } case RawPtr: // For these, flip the call around to cut down case OopPtr: case InstPtr: // on the cases I have to handle. case AryPtr:
*** 2258,2268 **** // Dual: compute field-by-field dual const TypePtr::PTR TypePtr::ptr_dual[TypePtr::lastPTR] = { BotPTR, NotNull, Constant, Null, AnyNull, TopPTR }; const Type *TypePtr::xdual() const { ! return new TypePtr( AnyPtr, dual_ptr(), dual_offset() ); } //------------------------------xadd_offset------------------------------------ int TypePtr::xadd_offset( intptr_t offset ) const { // Adding to 'TOP' offset? Return 'TOP'! --- 2301,2311 ---- // Dual: compute field-by-field dual const TypePtr::PTR TypePtr::ptr_dual[TypePtr::lastPTR] = { BotPTR, NotNull, Constant, Null, AnyNull, TopPTR }; const Type *TypePtr::xdual() const { ! return new TypePtr(AnyPtr, dual_ptr(), dual_offset(), dual_speculative(), dual_inline_depth()); } //------------------------------xadd_offset------------------------------------ int TypePtr::xadd_offset( intptr_t offset ) const { // Adding to 'TOP' offset? Return 'TOP'!
*** 2279,2302 **** return (int)offset; // Sum valid offsets } //------------------------------add_offset------------------------------------- const TypePtr *TypePtr::add_offset( intptr_t offset ) const { ! return make( AnyPtr, _ptr, xadd_offset(offset) ); } //------------------------------eq--------------------------------------------- // Structural equality check for Type representations bool TypePtr::eq( const Type *t ) const { const TypePtr *a = (const TypePtr*)t; ! return _ptr == a->ptr() && _offset == a->offset(); } //------------------------------hash------------------------------------------- // Type-specific hashing function. int TypePtr::hash(void) const { ! return _ptr + _offset; } //------------------------------dump2------------------------------------------ const char *const TypePtr::ptr_msg[TypePtr::lastPTR] = { "TopPTR","AnyNull","Constant","NULL","NotNull","BotPTR" --- 2322,2570 ---- return (int)offset; // Sum valid offsets } //------------------------------add_offset------------------------------------- const TypePtr *TypePtr::add_offset( intptr_t offset ) const { ! return make(AnyPtr, _ptr, xadd_offset(offset), _speculative, _inline_depth); } //------------------------------eq--------------------------------------------- // Structural equality check for Type representations bool TypePtr::eq( const Type *t ) const { const TypePtr *a = (const TypePtr*)t; ! return _ptr == a->ptr() && _offset == a->offset() && eq_speculative(a) && _inline_depth == a->_inline_depth; } //------------------------------hash------------------------------------------- // Type-specific hashing function. int TypePtr::hash(void) const { ! return _ptr + _offset + hash_speculative() + _inline_depth; ! ; ! } ! ! /** ! * Return same type without a speculative part ! */ ! const Type* TypePtr::remove_speculative() const { ! if (_speculative == NULL) { ! return this; ! } ! assert(_inline_depth == InlineDepthTop || _inline_depth == InlineDepthBottom, "non speculative type shouldn't have inline depth"); ! return make(AnyPtr, _ptr, _offset, NULL, _inline_depth); ! } ! ! /** ! * Return same type but drop speculative part if we know we won't use ! * it ! */ ! const Type* TypePtr::cleanup_speculative() const { ! if (speculative() == NULL) { ! return this; ! } ! const Type* no_spec = remove_speculative(); ! // If this is NULL_PTR then we don't need the speculative type ! // (with_inline_depth in case the current type inline depth is ! // InlineDepthTop) ! if (no_spec == NULL_PTR->with_inline_depth(inline_depth())) { ! return no_spec; ! } ! if (above_centerline(speculative()->ptr())) { ! return no_spec; ! } ! const TypeOopPtr* spec_oopptr = speculative()->isa_oopptr(); ! // If the speculative may be null and is an inexact klass then it ! // doesn't help ! if (speculative()->maybe_null() && (spec_oopptr == NULL || !spec_oopptr->klass_is_exact())) { ! return no_spec; ! } ! return this; ! } ! ! /** ! * dual of the speculative part of the type ! */ ! const TypePtr* TypePtr::dual_speculative() const { ! if (_speculative == NULL) { ! return NULL; ! } ! return _speculative->dual()->is_ptr(); ! } ! ! /** ! * meet of the speculative parts of 2 types ! * ! * @param other type to meet with ! */ ! const TypePtr* TypePtr::xmeet_speculative(const TypePtr* other) const { ! bool this_has_spec = (_speculative != NULL); ! bool other_has_spec = (other->speculative() != NULL); ! ! if (!this_has_spec && !other_has_spec) { ! return NULL; ! } ! ! // If we are at a point where control flow meets and one branch has ! // a speculative type and the other has not, we meet the speculative ! // type of one branch with the actual type of the other. If the ! // actual type is exact and the speculative is as well, then the ! // result is a speculative type which is exact and we can continue ! // speculation further. ! const TypePtr* this_spec = _speculative; ! const TypePtr* other_spec = other->speculative(); ! ! if (!this_has_spec) { ! this_spec = this; ! } ! ! if (!other_has_spec) { ! other_spec = other; ! } ! ! return this_spec->meet(other_spec)->is_ptr(); ! } ! ! /** ! * dual of the inline depth for this type (used for speculation) ! */ ! int TypePtr::dual_inline_depth() const { ! return -inline_depth(); ! } ! ! /** ! * meet of 2 inline depths (used for speculation) ! * ! * @param depth depth to meet with ! */ ! int TypePtr::meet_inline_depth(int depth) const { ! return MAX2(inline_depth(), depth); ! } ! ! /** ! * Are the speculative parts of 2 types equal? ! * ! * @param other type to compare this one to ! */ ! bool TypePtr::eq_speculative(const TypePtr* other) const { ! if (_speculative == NULL || other->speculative() == NULL) { ! return _speculative == other->speculative(); ! } ! ! if (_speculative->base() != other->speculative()->base()) { ! return false; ! } ! ! return _speculative->eq(other->speculative()); ! } ! ! /** ! * Hash of the speculative part of the type ! */ ! int TypePtr::hash_speculative() const { ! if (_speculative == NULL) { ! return 0; ! } ! ! return _speculative->hash(); ! } ! ! /** ! * add offset to the speculative part of the type ! * ! * @param offset offset to add ! */ ! const TypePtr* TypePtr::add_offset_speculative(intptr_t offset) const { ! if (_speculative == NULL) { ! return NULL; ! } ! return _speculative->add_offset(offset)->is_ptr(); ! } ! ! /** ! * return exact klass from the speculative type if there's one ! */ ! ciKlass* TypePtr::speculative_type() const { ! if (_speculative != NULL && _speculative->isa_oopptr()) { ! const TypeOopPtr* speculative = _speculative->join(this)->is_oopptr(); ! if (speculative->klass_is_exact()) { ! return speculative->klass(); ! } ! } ! return NULL; ! } ! ! /** ! * return true if speculative type may be null ! */ ! bool TypePtr::speculative_maybe_null() const { ! if (_speculative != NULL) { ! const TypePtr* speculative = _speculative->join(this)->is_ptr(); ! return speculative->maybe_null(); ! } ! return true; ! } ! ! /** ! * Same as TypePtr::speculative_type() but return the klass only if ! * the speculative tells us is not null ! */ ! ciKlass* TypePtr::speculative_type_not_null() const { ! if (speculative_maybe_null()) { ! return NULL; ! } ! return speculative_type(); ! } ! ! /** ! * 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 TypePtr::would_improve_type(ciKlass* exact_kls, int inline_depth) const { ! // 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(); ! } ! ! /** ! * Check whether new profiling would improve ptr (= tells us it is non ! * null) ! * ! * @param maybe_null true if profiling tells the ptr may be null ! * ! * @return true if ptr profile is valuable ! */ ! bool TypePtr::would_improve_ptr(bool maybe_null) const { ! // profiling doesn't tell us anything useful ! if (maybe_null) { ! return false; ! } ! // We already know this is not be null ! if (!this->maybe_null()) { ! return false; ! } ! // We already know the speculative type cannot be null ! if (!speculative_maybe_null()) { ! return false; ! } ! return true; } //------------------------------dump2------------------------------------------ const char *const TypePtr::ptr_msg[TypePtr::lastPTR] = { "TopPTR","AnyNull","Constant","NULL","NotNull","BotPTR"
*** 2307,2316 **** --- 2575,2610 ---- if( _ptr == Null ) st->print("NULL"); else st->print("%s *", ptr_msg[_ptr]); if( _offset == OffsetTop ) st->print("+top"); else if( _offset == OffsetBot ) st->print("+bot"); else if( _offset ) st->print("+%d", _offset); + dump_inline_depth(st); + dump_speculative(st); + } + + /** + *dump the speculative part of the type + */ + void TypePtr::dump_speculative(outputStream *st) const { + if (_speculative != NULL) { + st->print(" (speculative="); + _speculative->dump_on(st); + st->print(")"); + } + } + + /** + *dump the inline depth of the type + */ + void TypePtr::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-------------------------------------- // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple
*** 2397,2407 **** case TypePtr::TopPTR: return this; case TypePtr::BotPTR: return t; case TypePtr::Null: if( _ptr == TypePtr::TopPTR ) return t; return TypeRawPtr::BOTTOM; ! case TypePtr::NotNull: return TypePtr::make( AnyPtr, meet_ptr(TypePtr::NotNull), tp->meet_offset(0) ); case TypePtr::AnyNull: if( _ptr == TypePtr::Constant) return this; return make( meet_ptr(TypePtr::AnyNull) ); default: ShouldNotReachHere(); } --- 2691,2701 ---- case TypePtr::TopPTR: return this; case TypePtr::BotPTR: return t; case TypePtr::Null: if( _ptr == TypePtr::TopPTR ) return t; return TypeRawPtr::BOTTOM; ! case TypePtr::NotNull: return TypePtr::make(AnyPtr, meet_ptr(TypePtr::NotNull), tp->meet_offset(0), tp->speculative(), tp->inline_depth()); case TypePtr::AnyNull: if( _ptr == TypePtr::Constant) return this; return make( meet_ptr(TypePtr::AnyNull) ); default: ShouldNotReachHere(); }
*** 2461,2480 **** //============================================================================= // Convenience common pre-built type. 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, int inline_depth) ! : TypePtr(t, ptr, offset), _const_oop(o), _klass(k), _klass_is_exact(xk), _is_ptr_to_narrowoop(false), _is_ptr_to_narrowklass(false), _is_ptr_to_boxed_value(false), ! _instance_id(instance_id), ! _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); } #ifdef _LP64 --- 2755,2773 ---- //============================================================================= // Convenience common pre-built type. const TypeOopPtr *TypeOopPtr::BOTTOM; //------------------------------TypeOopPtr------------------------------------- ! TypeOopPtr::TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, ! int instance_id, const TypePtr* speculative, int inline_depth) ! : TypePtr(t, ptr, offset, speculative, inline_depth), _const_oop(o), _klass(k), _klass_is_exact(xk), _is_ptr_to_narrowoop(false), _is_ptr_to_narrowklass(false), _is_ptr_to_boxed_value(false), ! _instance_id(instance_id) { 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); } #ifdef _LP64
*** 2536,2547 **** } #endif } //------------------------------make------------------------------------------- ! const TypeOopPtr *TypeOopPtr::make(PTR ptr, ! 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, inline_depth))->hashcons(); --- 2829,2840 ---- } #endif } //------------------------------make------------------------------------------- ! const TypeOopPtr *TypeOopPtr::make(PTR ptr, int offset, int instance_id, ! const TypePtr* 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, inline_depth))->hashcons();
*** 2580,2611 **** return TypeKlassPtr::OBJECT; else return TypeKlassPtr::make(xk? Constant: NotNull, k, 0); } - const Type *TypeOopPtr::xmeet(const Type *t) const { - const Type* res = xmeet_helper(t); - if (res->isa_oopptr() == NULL) { - return res; - } - - const TypeOopPtr* res_oopptr = res->is_oopptr(); - if (res_oopptr->speculative() != NULL) { - // type->speculative() == NULL means that speculation is no better - // than type, i.e. type->speculative() == type. So there are 2 - // ways to represent the fact that we have no useful speculative - // data and we should use a single one to be able to test for - // equality between types. Check whether type->speculative() == - // type and set speculative to NULL if it is the case. - if (res_oopptr->remove_speculative() == res_oopptr->speculative()) { - return res_oopptr->remove_speculative(); - } - } - - return res; - } - //------------------------------meet------------------------------------------- // Compute the MEET of two types. It returns a new Type object. const Type *TypeOopPtr::xmeet_helper(const Type *t) const { // Perform a fast test for common case; meeting the same types together. if( this == t ) return this; // Meeting same type-rep? --- 2873,2882 ----
*** 2639,2669 **** case AnyPtr: { // Found an AnyPtr type vs self-OopPtr type const TypePtr *tp = t->is_ptr(); int offset = meet_offset(tp->offset()); PTR ptr = meet_ptr(tp->ptr()); switch (tp->ptr()) { case Null: ! if (ptr == Null) return TypePtr::make(AnyPtr, ptr, offset); // else fall through: case TopPTR: case AnyNull: { int instance_id = meet_instance_id(InstanceTop); ! const TypeOopPtr* speculative = _speculative; ! return make(ptr, offset, instance_id, speculative, _inline_depth); } case BotPTR: case NotNull: ! return TypePtr::make(AnyPtr, ptr, offset); default: typerr(t); } } case OopPtr: { // Meeting to other OopPtrs const TypeOopPtr *tp = t->is_oopptr(); int instance_id = meet_instance_id(tp->instance_id()); ! const TypeOopPtr* speculative = xmeet_speculative(tp); 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 --- 2910,2941 ---- case AnyPtr: { // Found an AnyPtr type vs self-OopPtr type const TypePtr *tp = t->is_ptr(); int offset = meet_offset(tp->offset()); PTR ptr = meet_ptr(tp->ptr()); + const TypePtr* speculative = xmeet_speculative(tp); + int depth = meet_inline_depth(tp->inline_depth()); switch (tp->ptr()) { case Null: ! if (ptr == Null) return TypePtr::make(AnyPtr, ptr, offset, speculative, depth); // else fall through: case TopPTR: case AnyNull: { int instance_id = meet_instance_id(InstanceTop); ! return make(ptr, offset, instance_id, speculative, depth); } case BotPTR: case NotNull: ! return TypePtr::make(AnyPtr, ptr, offset, speculative, depth); default: typerr(t); } } case OopPtr: { // Meeting to other OopPtrs const TypeOopPtr *tp = t->is_oopptr(); int instance_id = meet_instance_id(tp->instance_id()); ! const TypePtr* speculative = xmeet_speculative(tp); 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
*** 2857,2869 **** //------------------------------eq--------------------------------------------- // Structural equality check for Type representations bool TypeOopPtr::eq( const Type *t ) const { const TypeOopPtr *a = (const TypeOopPtr*)t; if (_klass_is_exact != a->_klass_is_exact || ! _instance_id != a->_instance_id || ! !eq_speculative(a) || ! _inline_depth != a->_inline_depth) return false; ciObject* one = const_oop(); ciObject* two = a->const_oop(); if (one == NULL || two == NULL) { return (one == two) && TypePtr::eq(t); } else { --- 3129,3139 ---- //------------------------------eq--------------------------------------------- // Structural equality check for Type representations bool TypeOopPtr::eq( const Type *t ) const { const TypeOopPtr *a = (const TypeOopPtr*)t; if (_klass_is_exact != a->_klass_is_exact || ! _instance_id != a->_instance_id) return false; ciObject* one = const_oop(); ciObject* two = a->const_oop(); if (one == NULL || two == NULL) { return (one == two) && TypePtr::eq(t); } else {
*** 2876,2887 **** int TypeOopPtr::hash(void) const { return (const_oop() ? const_oop()->hash() : 0) + _klass_is_exact + _instance_id + - hash_speculative() + - _inline_depth + TypePtr::hash(); } //------------------------------dump2------------------------------------------ #ifndef PRODUCT --- 3146,3155 ----
*** 2901,2931 **** st->print(",iid=%d",_instance_id); dump_inline_depth(st); dump_speculative(st); } - - /** - *dump the speculative part of the type - */ - void TypeOopPtr::dump_speculative(outputStream *st) const { - if (_speculative != NULL) { - st->print(" (speculative="); - _speculative->dump_on(st); - 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-------------------------------------- // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple // constants --- 3169,3178 ----
*** 2950,3000 **** 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-------------------------------- int TypeOopPtr::meet_instance_id( int instance_id ) const { // Either is 'TOP' instance? Return the other instance! --- 3197,3228 ---- 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 drop speculative part if we know we won't use ! * it */ ! const Type* TypeOopPtr::cleanup_speculative() const { ! // If the klass is exact and the ptr is not null then there's ! // nothing that the speculative type can help us with ! if (klass_is_exact() && !maybe_null()) { ! return remove_speculative(); } ! return TypePtr::cleanup_speculative(); } /** ! * Return same type but with a different inline depth (used for speculation) * ! * @param depth depth to meet with */ ! const TypePtr* TypeOopPtr::with_inline_depth(int depth) const { ! if (!UseInlineDepthForSpeculativeTypes) { ! return this; } ! return make(_ptr, _offset, _instance_id, _speculative, depth); } //------------------------------meet_instance_id-------------------------------- int TypeOopPtr::meet_instance_id( int instance_id ) const { // Either is 'TOP' instance? Return the other instance!
*** 3011,3116 **** if( _instance_id == InstanceBot ) return InstanceTop; // Map BOTTOM into TOP return _instance_id; // Map everything else into self } /** ! * meet of the speculative parts of 2 types ! * ! * @param other type to meet with ! */ ! const TypeOopPtr* TypeOopPtr::xmeet_speculative(const TypeOopPtr* other) const { ! bool this_has_spec = (_speculative != NULL); ! bool other_has_spec = (other->speculative() != NULL); ! ! if (!this_has_spec && !other_has_spec) { ! return NULL; ! } ! ! // If we are at a point where control flow meets and one branch has ! // a speculative type and the other has not, we meet the speculative ! // type of one branch with the actual type of the other. If the ! // actual type is exact and the speculative is as well, then the ! // result is a speculative type which is exact and we can continue ! // speculation further. ! const TypeOopPtr* this_spec = _speculative; ! const TypeOopPtr* other_spec = other->speculative(); ! ! if (!this_has_spec) { ! this_spec = this; ! } ! ! if (!other_has_spec) { ! other_spec = other; ! } ! ! return this_spec->meet_speculative(other_spec)->is_oopptr(); ! } ! ! /** ! * dual of the speculative part of the type ! */ ! const TypeOopPtr* TypeOopPtr::dual_speculative() const { ! if (_speculative == NULL) { ! return NULL; ! } ! return _speculative->dual()->is_oopptr(); ! } ! ! /** ! * add offset to the speculative part of the type * ! * @param offset offset to add ! */ ! const TypeOopPtr* TypeOopPtr::add_offset_speculative(intptr_t offset) const { ! if (_speculative == NULL) { ! return NULL; ! } ! return _speculative->add_offset(offset)->is_oopptr(); ! } ! ! /** ! * Are the speculative parts of 2 types equal? * ! * @param other type to compare this one to */ ! bool TypeOopPtr::eq_speculative(const TypeOopPtr* other) const { ! if (_speculative == NULL || other->speculative() == NULL) { ! return _speculative == other->speculative(); ! } ! ! if (_speculative->base() != other->speculative()->base()) { return false; } ! ! return _speculative->eq(other->speculative()); ! } ! ! /** ! * Hash of the speculative part of the type ! */ ! int TypeOopPtr::hash_speculative() const { ! if (_speculative == NULL) { ! return 0; ! } ! ! 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. const TypeInstPtr *TypeInstPtr::NOTNULL; --- 3239,3261 ---- if( _instance_id == InstanceBot ) return InstanceTop; // Map BOTTOM into TOP return _instance_id; // Map everything else into self } /** ! * 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; } ! return TypePtr::would_improve_type(exact_kls, inline_depth); } //============================================================================= // Convenience common pre-built types. const TypeInstPtr *TypeInstPtr::NOTNULL;
*** 3118,3129 **** const TypeInstPtr *TypeInstPtr::MIRROR; const TypeInstPtr *TypeInstPtr::MARK; const TypeInstPtr *TypeInstPtr::KLASS; //------------------------------TypeInstPtr------------------------------------- ! 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"); }; --- 3263,3276 ---- const TypeInstPtr *TypeInstPtr::MIRROR; const TypeInstPtr *TypeInstPtr::MARK; const TypeInstPtr *TypeInstPtr::KLASS; //------------------------------TypeInstPtr------------------------------------- ! TypeInstPtr::TypeInstPtr(PTR ptr, ciKlass* k, bool xk, ciObject* o, int off, ! int instance_id, const TypePtr* 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"); };
*** 3132,3142 **** ciKlass* k, bool xk, ciObject* o, int offset, int instance_id, ! 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), "constant pointers must have a value supplied" ); --- 3279,3289 ---- ciKlass* k, bool xk, ciObject* o, int offset, int instance_id, ! const TypePtr* 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), "constant pointers must have a value supplied" );
*** 3215,3225 **** // Assume classes are different since called after check for same name/class-loader const TypeInstPtr *TypeInstPtr::xmeet_unloaded(const TypeInstPtr *tinst) const { int off = meet_offset(tinst->offset()); 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; if( loaded->klass()->equals(ciEnv::current()->Object_klass()) ) { --- 3362,3372 ---- // Assume classes are different since called after check for same name/class-loader const TypeInstPtr *TypeInstPtr::xmeet_unloaded(const TypeInstPtr *tinst) const { int off = meet_offset(tinst->offset()); PTR ptr = meet_ptr(tinst->ptr()); int instance_id = meet_instance_id(tinst->instance_id()); ! const TypePtr* 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; if( loaded->klass()->equals(ciEnv::current()->Object_klass()) ) {
*** 3293,3303 **** case AryPtr: { // All arrays inherit from Object class const TypeAryPtr *tp = t->is_aryptr(); int offset = meet_offset(tp->offset()); 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 // For instances when a subclass meets a superclass we fall --- 3440,3450 ---- case AryPtr: { // All arrays inherit from Object class const TypeAryPtr *tp = t->is_aryptr(); int offset = meet_offset(tp->offset()); PTR ptr = meet_ptr(tp->ptr()); int instance_id = meet_instance_id(tp->instance_id()); ! const TypePtr* 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 // For instances when a subclass meets a superclass we fall
*** 3344,3362 **** PTR ptr = meet_ptr(tp->ptr()); switch (tp->ptr()) { case TopPTR: 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, depth); } case NotNull: case BotPTR: { int instance_id = meet_instance_id(tp->instance_id()); ! const TypeOopPtr* speculative = xmeet_speculative(tp); int depth = meet_inline_depth(tp->inline_depth()); return TypeOopPtr::make(ptr, offset, instance_id, speculative, depth); } default: typerr(t); } --- 3491,3509 ---- PTR ptr = meet_ptr(tp->ptr()); switch (tp->ptr()) { case TopPTR: case AnyNull: { int instance_id = meet_instance_id(InstanceTop); ! const TypePtr* 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, depth); } case NotNull: case BotPTR: { int instance_id = meet_instance_id(tp->instance_id()); ! const TypePtr* speculative = xmeet_speculative(tp); int depth = meet_inline_depth(tp->inline_depth()); return TypeOopPtr::make(ptr, offset, instance_id, speculative, depth); } default: typerr(t); }
*** 3365,3388 **** case AnyPtr: { // Meeting to AnyPtrs // Found an AnyPtr type vs self-InstPtr type const TypePtr *tp = t->is_ptr(); int offset = meet_offset(tp->offset()); PTR ptr = meet_ptr(tp->ptr()); switch (tp->ptr()) { case Null: ! if( ptr == Null ) return TypePtr::make(AnyPtr, ptr, offset); // else fall through to AnyNull case TopPTR: case AnyNull: { - 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, _inline_depth); } case NotNull: case BotPTR: ! return TypePtr::make(AnyPtr, ptr, offset); default: typerr(t); } } /* --- 3512,3536 ---- case AnyPtr: { // Meeting to AnyPtrs // Found an AnyPtr type vs self-InstPtr type const TypePtr *tp = t->is_ptr(); int offset = meet_offset(tp->offset()); PTR ptr = meet_ptr(tp->ptr()); + int instance_id = meet_instance_id(InstanceTop); + const TypePtr* speculative = xmeet_speculative(tp); + int depth = meet_inline_depth(tp->inline_depth()); switch (tp->ptr()) { case Null: ! if( ptr == Null ) return TypePtr::make(AnyPtr, ptr, offset, speculative, depth); // else fall through to AnyNull case TopPTR: case AnyNull: { return make(ptr, klass(), klass_is_exact(), ! (ptr == Constant ? const_oop() : NULL), offset, instance_id, speculative, depth); } case NotNull: case BotPTR: ! return TypePtr::make(AnyPtr, ptr, offset, speculative,depth); default: typerr(t); } } /*
*** 3405,3415 **** // Found an InstPtr sub-type vs self-InstPtr type const TypeInstPtr *tinst = t->is_instptr(); int off = meet_offset( tinst->offset() ); 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 --- 3553,3563 ---- // Found an InstPtr sub-type vs self-InstPtr type const TypeInstPtr *tinst = t->is_instptr(); int off = meet_offset( tinst->offset() ); PTR ptr = meet_ptr( tinst->ptr() ); int instance_id = meet_instance_id(tinst->instance_id()); ! const TypePtr* 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
*** 3561,3570 **** --- 3709,3719 ---- // Since klasses are different, we require a LCA in the Java // class hierarchy - which means we have to fall to at least NotNull. if( ptr == TopPTR || ptr == AnyNull || ptr == Constant ) ptr = NotNull; + instance_id = InstanceBot; // 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, depth);
*** 3653,3674 **** } #endif //------------------------------add_offset------------------------------------- const TypePtr *TypeInstPtr::add_offset(intptr_t offset) const { ! return make(_ptr, klass(), klass_is_exact(), const_oop(), xadd_offset(offset), _instance_id, add_offset_speculative(offset)); } const Type *TypeInstPtr::remove_speculative() const { if (_speculative == NULL) { return this; } 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); } --- 3802,3825 ---- } #endif //------------------------------add_offset------------------------------------- const TypePtr *TypeInstPtr::add_offset(intptr_t offset) const { ! return make(_ptr, klass(), klass_is_exact(), const_oop(), xadd_offset(offset), ! _instance_id, add_offset_speculative(offset), _inline_depth); } const Type *TypeInstPtr::remove_speculative() const { if (_speculative == NULL) { return this; } 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 TypePtr *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); }
*** 3685,3705 **** const TypeAryPtr *TypeAryPtr::LONGS; const TypeAryPtr *TypeAryPtr::FLOATS; 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, 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, 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, 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"); --- 3836,3859 ---- const TypeAryPtr *TypeAryPtr::LONGS; const TypeAryPtr *TypeAryPtr::FLOATS; const TypeAryPtr *TypeAryPtr::DOUBLES; //------------------------------make------------------------------------------- ! const TypeAryPtr *TypeAryPtr::make(PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, ! int instance_id, const TypePtr* 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, 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 TypePtr* 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");
*** 3805,3815 **** elem = elem_ptr = elem_ptr->is_aryptr()->cast_to_stable(stable, stable_dimension - 1); } const TypeAry* new_ary = TypeAry::make(elem, size(), stable); ! return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id); } //-----------------------------stable_dimension-------------------------------- int TypeAryPtr::stable_dimension() const { if (!is_stable()) return 0; --- 3959,3969 ---- elem = elem_ptr = elem_ptr->is_aryptr()->cast_to_stable(stable, stable_dimension - 1); } const TypeAry* new_ary = TypeAry::make(elem, size(), stable); ! return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id, _speculative, _inline_depth); } //-----------------------------stable_dimension-------------------------------- int TypeAryPtr::stable_dimension() const { if (!is_stable()) return 0;
*** 3866,3887 **** // Found a OopPtr type vs self-AryPtr type 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, 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, depth); } default: ShouldNotReachHere(); } } --- 4020,4040 ---- // Found a OopPtr type vs self-AryPtr type 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()); + const TypePtr* speculative = xmeet_speculative(tp); switch (tp->ptr()) { case TopPTR: case AnyNull: { int instance_id = meet_instance_id(InstanceTop); return make(ptr, (ptr == Constant ? const_oop() : NULL), _ary, _klass, _klass_is_exact, offset, instance_id, speculative, depth); } case BotPTR: case NotNull: { int instance_id = meet_instance_id(tp->instance_id()); return TypeOopPtr::make(ptr, offset, instance_id, speculative, depth); } default: ShouldNotReachHere(); } }
*** 3889,3912 **** case AnyPtr: { // Meeting two AnyPtrs // Found an AnyPtr type vs self-AryPtr type const TypePtr *tp = t->is_ptr(); int offset = meet_offset(tp->offset()); PTR ptr = meet_ptr(tp->ptr()); switch (tp->ptr()) { case TopPTR: return this; case BotPTR: case NotNull: ! return TypePtr::make(AnyPtr, ptr, offset); case Null: ! if( ptr == Null ) return TypePtr::make(AnyPtr, ptr, offset); // else fall through to AnyNull case AnyNull: { 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, _inline_depth); } default: ShouldNotReachHere(); } } --- 4042,4066 ---- case AnyPtr: { // Meeting two AnyPtrs // Found an AnyPtr type vs self-AryPtr type const TypePtr *tp = t->is_ptr(); int offset = meet_offset(tp->offset()); PTR ptr = meet_ptr(tp->ptr()); + const TypePtr* speculative = xmeet_speculative(tp); + int depth = meet_inline_depth(tp->inline_depth()); switch (tp->ptr()) { case TopPTR: return this; case BotPTR: case NotNull: ! return TypePtr::make(AnyPtr, ptr, offset, speculative, depth); case Null: ! if( ptr == Null ) return TypePtr::make(AnyPtr, ptr, offset, speculative, depth); // else fall through to AnyNull case AnyNull: { int instance_id = meet_instance_id(InstanceTop); return make(ptr, (ptr == Constant ? const_oop() : NULL), ! _ary, _klass, _klass_is_exact, offset, instance_id, speculative, depth); } default: ShouldNotReachHere(); } }
*** 3918,3928 **** const TypeAryPtr *tap = t->is_aryptr(); int off = meet_offset(tap->offset()); const TypeAry *tary = _ary->meet_speculative(tap->_ary)->is_ary(); 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. // It is the klass that determines array layout, not the element type. --- 4072,4082 ---- const TypeAryPtr *tap = t->is_aryptr(); int off = meet_offset(tap->offset()); const TypeAry *tary = _ary->meet_speculative(tap->_ary)->is_ary(); PTR ptr = meet_ptr(tap->ptr()); int instance_id = meet_instance_id(tap->instance_id()); ! const TypePtr* 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. // It is the klass that determines array layout, not the element type.
*** 3947,3957 **** // 'tap' is exact and super or unrelated: (tap->_klass_is_exact && !tap->klass()->is_subtype_of(klass())) || // 'this' is exact and super or unrelated: (this->_klass_is_exact && !klass()->is_subtype_of(tap->klass())))) { tary = TypeAry::make(Type::BOTTOM, tary->_size, tary->_stable); ! return make(NotNull, NULL, tary, lazy_klass, false, off, InstanceBot); } bool xk = false; switch (tap->ptr()) { case AnyNull: --- 4101,4111 ---- // 'tap' is exact and super or unrelated: (tap->_klass_is_exact && !tap->klass()->is_subtype_of(klass())) || // 'this' is exact and super or unrelated: (this->_klass_is_exact && !klass()->is_subtype_of(tap->klass())))) { tary = TypeAry::make(Type::BOTTOM, tary->_size, tary->_stable); ! return make(NotNull, NULL, tary, lazy_klass, false, off, InstanceBot, speculative, depth); } bool xk = false; switch (tap->ptr()) { case AnyNull:
*** 3999,4009 **** case InstPtr: { const TypeInstPtr *tp = t->is_instptr(); int offset = meet_offset(tp->offset()); 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 // For instances when a subclass meets a superclass we fall --- 4153,4163 ---- case InstPtr: { const TypeInstPtr *tp = t->is_instptr(); int offset = meet_offset(tp->offset()); PTR ptr = meet_ptr(tp->ptr()); int instance_id = meet_instance_id(tp->instance_id()); ! const TypePtr* 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 // For instances when a subclass meets a superclass we fall
*** 4123,4133 **** } 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); } --- 4277,4287 ---- } 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 TypePtr *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); }
*** 4248,4257 **** --- 4402,4418 ---- const TypeNarrowOop* TypeNarrowOop::make(const TypePtr* type) { return (const TypeNarrowOop*)(new TypeNarrowOop(type))->hashcons(); } + const Type* TypeNarrowOop::remove_speculative() const { + return make(_ptrtype->remove_speculative()->is_ptr()); + } + + const Type* TypeNarrowOop::cleanup_speculative() const { + return make(_ptrtype->cleanup_speculative()->is_ptr()); + } #ifndef PRODUCT void TypeNarrowOop::dump2( Dict & d, uint depth, outputStream *st ) const { st->print("narrowoop: "); TypeNarrowPtr::dump2(d, depth, st);
*** 4374,4392 **** const TypePtr *tp = t->is_ptr(); int offset = meet_offset(tp->offset()); PTR ptr = meet_ptr(tp->ptr()); switch (tp->ptr()) { case Null: ! if (ptr == Null) return TypePtr::make(AnyPtr, ptr, offset); // else fall through: case TopPTR: case AnyNull: { return make(ptr, _metadata, offset); } case BotPTR: case NotNull: ! return TypePtr::make(AnyPtr, ptr, offset); default: typerr(t); } } case RawPtr: --- 4535,4553 ---- const TypePtr *tp = t->is_ptr(); int offset = meet_offset(tp->offset()); PTR ptr = meet_ptr(tp->ptr()); switch (tp->ptr()) { case Null: ! if (ptr == Null) return TypePtr::make(AnyPtr, ptr, offset, tp->speculative(), tp->inline_depth()); // else fall through: case TopPTR: case AnyNull: { return make(ptr, _metadata, offset); } case BotPTR: case NotNull: ! return TypePtr::make(AnyPtr, ptr, offset, tp->speculative(), tp->inline_depth()); default: typerr(t); } } case RawPtr:
*** 4696,4711 **** PTR ptr = meet_ptr(tp->ptr()); switch (tp->ptr()) { case TopPTR: return this; case Null: ! if( ptr == Null ) return TypePtr::make( AnyPtr, ptr, offset ); case AnyNull: return make( ptr, klass(), offset ); case BotPTR: case NotNull: ! return TypePtr::make(AnyPtr, ptr, offset); default: typerr(t); } } case RawPtr: --- 4857,4872 ---- PTR ptr = meet_ptr(tp->ptr()); switch (tp->ptr()) { case TopPTR: return this; case Null: ! if( ptr == Null ) return TypePtr::make(AnyPtr, ptr, offset, tp->speculative(), tp->inline_depth()); case AnyNull: return make( ptr, klass(), offset ); case BotPTR: case NotNull: ! return TypePtr::make(AnyPtr, ptr, offset, tp->speculative(), tp->inline_depth()); default: typerr(t); } } case RawPtr:
src/share/vm/opto/type.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File