Mercurial > hg > graal-compiler
diff src/share/vm/opto/type.cpp @ 10408:836a62f43af9
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 19 Jun 2013 10:45:56 +0200 |
parents | 6f3fd5150b67 |
children | edb5ab0f3fe5 7944aba7ba41 |
line wrap: on
line diff
--- a/src/share/vm/opto/type.cpp Tue Jun 18 14:23:29 2013 -0700 +++ b/src/share/vm/opto/type.cpp Wed Jun 19 10:45:56 2013 +0200 @@ -2372,7 +2372,12 @@ _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 if (_offset != 0) { if (_offset == oopDesc::klass_offset_in_bytes()) { @@ -2613,44 +2618,50 @@ //------------------------------make_from_constant----------------------------- // Make a java pointer from an oop constant -const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o, bool require_constant) { - assert(!o->is_null_object(), "null object not yet handled here."); - ciKlass* klass = o->klass(); - if (klass->is_instance_klass()) { - // Element is an instance - if (require_constant) { - if (!o->can_be_constant()) return NULL; - } else if (!o->should_be_constant()) { - return TypeInstPtr::make(TypePtr::NotNull, klass, true, NULL, 0); - } - return TypeInstPtr::make(o); - } else if (klass->is_obj_array_klass()) { - // Element is an object array. Recursively call ourself. - const Type *etype = +const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o, + bool require_constant, + bool is_autobox_cache) { + assert(!o->is_null_object(), "null object not yet handled here."); + ciKlass* klass = o->klass(); + if (klass->is_instance_klass()) { + // Element is an instance + if (require_constant) { + if (!o->can_be_constant()) return NULL; + } else if (!o->should_be_constant()) { + return TypeInstPtr::make(TypePtr::NotNull, klass, true, NULL, 0); + } + return TypeInstPtr::make(o); + } else if (klass->is_obj_array_klass()) { + // Element is an object array. Recursively call ourself. + const TypeOopPtr *etype = TypeOopPtr::make_from_klass_raw(klass->as_obj_array_klass()->element_klass()); - const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length())); - // We used to pass NotNull in here, asserting that the sub-arrays - // are all not-null. This is not true in generally, as code can - // slam NULLs down in the subarrays. - if (require_constant) { - if (!o->can_be_constant()) return NULL; - } 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); + if (is_autobox_cache) { + // The pointers in the autobox arrays are always non-null. + etype = etype->cast_to_ptr_type(TypePtr::NotNull)->is_oopptr(); + } + const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length())); + // We used to pass NotNull in here, asserting that the sub-arrays + // are all not-null. This is not true in generally, as code can + // slam NULLs down in the subarrays. + if (require_constant) { + if (!o->can_be_constant()) return NULL; + } 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, is_autobox_cache); return arr; - } else if (klass->is_type_array_klass()) { - // Element is an typeArray + } else if (klass->is_type_array_klass()) { + // Element is an typeArray const Type* etype = (Type*)get_const_basic_type(klass->as_type_array_klass()->element_type()); - const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length())); - // We used to pass NotNull in here, asserting that the array pointer - // is not-null. That was not true in general. - if (require_constant) { - if (!o->can_be_constant()) return NULL; - } else if (!o->should_be_constant()) { - return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0); - } + const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length())); + // We used to pass NotNull in here, asserting that the array pointer + // is not-null. That was not true in general. + if (require_constant) { + if (!o->can_be_constant()) return NULL; + } 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); return arr; } @@ -2856,6 +2867,28 @@ return result; } +/** + * Create constant type for a constant boxed value + */ +const Type* TypeInstPtr::get_const_boxed_value() const { + assert(is_ptr_to_boxed_value(), "should be called only for boxed value"); + assert((const_oop() != NULL), "should be called only for constant object"); + ciConstant constant = const_oop()->as_instance()->field_value_by_offset(offset()); + BasicType bt = constant.basic_type(); + switch (bt) { + case T_BOOLEAN: return TypeInt::make(constant.as_boolean()); + case T_INT: return TypeInt::make(constant.as_int()); + case T_CHAR: return TypeInt::make(constant.as_char()); + case T_BYTE: return TypeInt::make(constant.as_byte()); + case T_SHORT: return TypeInt::make(constant.as_short()); + case T_FLOAT: return TypeF::make(constant.as_float()); + case T_DOUBLE: return TypeD::make(constant.as_double()); + case T_LONG: return TypeLong::make(constant.as_long()); + default: break; + } + fatal(err_msg_res("Invalid boxed value type '%s'", type2name(bt))); + return NULL; +} //------------------------------cast_to_ptr_type------------------------------- const Type *TypeInstPtr::cast_to_ptr_type(PTR ptr) const { @@ -3330,18 +3363,18 @@ 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))->hashcons(); + return (TypeAryPtr*)(new TypeAryPtr(ptr, NULL, ary, k, xk, offset, instance_id, false))->hashcons(); } //------------------------------make------------------------------------------- -const TypeAryPtr *TypeAryPtr::make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id ) { +const TypeAryPtr *TypeAryPtr::make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id, 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))->hashcons(); + return (TypeAryPtr*)(new TypeAryPtr(ptr, o, ary, k, xk, offset, instance_id, is_autobox_cache))->hashcons(); } //------------------------------cast_to_ptr_type------------------------------- @@ -3397,8 +3430,20 @@ jint max_hi = max_array_length(elem()->basic_type()); //if (index_not_size) --max_hi; // type of a valid array index, FTR bool chg = false; - if (lo < min_lo) { lo = min_lo; chg = true; } - if (hi > max_hi) { hi = max_hi; chg = true; } + if (lo < min_lo) { + lo = min_lo; + if (size->is_con()) { + hi = lo; + } + chg = true; + } + if (hi > max_hi) { + hi = max_hi; + if (size->is_con()) { + lo = hi; + } + chg = true; + } // Negative length arrays will produce weird intermediate dead fast-path code if (lo > hi) return TypeInt::ZERO; @@ -3630,7 +3675,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() ); + return new TypeAryPtr( dual_ptr(), _const_oop, _ary->dual()->is_ary(),_klass, _klass_is_exact, dual_offset(), dual_instance_id(), is_autobox_cache() ); } //----------------------interface_vs_oop---------------------------------------