< 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 >