< prev index next >

src/hotspot/share/opto/memnode.cpp

Print this page

        

*** 1846,1860 **** // unsafe field access may not have a constant offset C->has_unsafe_access(), "Field accesses must be precise" ); // For oop loads, we expect the _type to be precise. - // Optimize loads from constant fields. const TypeInstPtr* tinst = tp->is_instptr(); ciObject* const_oop = tinst->const_oop(); if (!is_mismatched_access() && off != Type::OffsetBot && const_oop != NULL && const_oop->is_instance()) { - BasicType bt = memory_type(); ciType* mirror_type = const_oop->as_instance()->java_mirror_type(); if (mirror_type != NULL && mirror_type->is_valuetype()) { ciValueKlass* vk = mirror_type->as_value_klass(); if (off == vk->default_value_offset()) { // Loading a special hidden field that contains the oop of the default value type --- 1846,1877 ---- // unsafe field access may not have a constant offset C->has_unsafe_access(), "Field accesses must be precise" ); // For oop loads, we expect the _type to be precise. const TypeInstPtr* tinst = tp->is_instptr(); + BasicType bt = memory_type(); + + // Fold component and value mirror loads + ciInstanceKlass* ik = tinst->klass()->as_instance_klass(); + if (ik == phase->C->env()->Class_klass() && (off == java_lang_Class::component_mirror_offset_in_bytes() || + off == java_lang_Class::value_mirror_offset_in_bytes())) { + ciType* mirror_type = tinst->java_mirror_type(); + if (mirror_type != NULL) { + const Type* const_oop = TypePtr::NULL_PTR; + if (mirror_type->is_array_klass()) { + const_oop = TypeInstPtr::make(mirror_type->as_array_klass()->component_mirror_instance()); + } else if (mirror_type->is_valuetype()) { + const_oop = TypeInstPtr::make(mirror_type->as_value_klass()->value_mirror_instance()); + } + return (bt == T_NARROWOOP) ? const_oop->make_narrowoop() : const_oop; + } + } + + // Optimize loads from constant fields. ciObject* const_oop = tinst->const_oop(); if (!is_mismatched_access() && off != Type::OffsetBot && const_oop != NULL && const_oop->is_instance()) { ciType* mirror_type = const_oop->as_instance()->java_mirror_type(); if (mirror_type != NULL && mirror_type->is_valuetype()) { ciValueKlass* vk = mirror_type->as_value_klass(); if (off == vk->default_value_offset()) { // Loading a special hidden field that contains the oop of the default value type
*** 2240,2258 **** ciKlass *tary_klass = tary->klass(); if (tary_klass != NULL // can be NULL when at BOTTOM or TOP && tary->offset() == oopDesc::klass_offset_in_bytes()) { ciArrayKlass* ak = tary_klass->as_array_klass(); // Do not fold klass loads from [V? because the runtime type might be [V due to [V <: [V? ! bool can_be_flattened = ak->is_obj_array_klass() && !ak->storage_properties().is_null_free() && ak->element_klass()->is_valuetype(); ! if (tary->klass_is_exact() && !can_be_flattened) { return TypeKlassPtr::make(tary_klass); } // If the klass is an object array, we defer the question to the // array component klass. ! if (ak->is_obj_array_klass() && !can_be_flattened) { assert(ak->is_loaded(), ""); ciKlass *base_k = ak->as_obj_array_klass()->base_element_klass(); if (base_k->is_loaded() && base_k->is_instance_klass()) { ciInstanceKlass *ik = base_k->as_instance_klass(); // See if we can become precise: no subklasses and no interface --- 2257,2275 ---- ciKlass *tary_klass = tary->klass(); if (tary_klass != NULL // can be NULL when at BOTTOM or TOP && tary->offset() == oopDesc::klass_offset_in_bytes()) { ciArrayKlass* ak = tary_klass->as_array_klass(); // Do not fold klass loads from [V? because the runtime type might be [V due to [V <: [V? ! bool can_be_null_free = !tary->is_known_instance() && ak->is_obj_array_klass() && !ak->storage_properties().is_null_free() && ak->element_klass()->is_valuetype(); ! if (tary->klass_is_exact() && !can_be_null_free) { return TypeKlassPtr::make(tary_klass); } // If the klass is an object array, we defer the question to the // array component klass. ! if (ak->is_obj_array_klass() && !can_be_null_free) { assert(ak->is_loaded(), ""); ciKlass *base_k = ak->as_obj_array_klass()->base_element_klass(); if (base_k->is_loaded() && base_k->is_instance_klass()) { ciInstanceKlass *ik = base_k->as_instance_klass(); // See if we can become precise: no subklasses and no interface
< prev index next >