src/share/vm/opto/memnode.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
7071709 Cdiff src/share/vm/opto/memnode.cpp
src/share/vm/opto/memnode.cpp
Print this page
*** 1491,1500 ****
--- 1491,1501 ----
Node* adr = in(MemNode::Address);
const TypePtr* tp = phase->type(adr)->isa_ptr();
if (tp == NULL || tp->empty()) return Type::TOP;
int off = tp->offset();
assert(off != Type::OffsetTop, "case covered by TypePtr::empty");
+ Compile* C = phase->C;
// Try to guess loaded type from pointer type
if (tp->base() == Type::AryPtr) {
const Type *t = tp->is_aryptr()->elem();
// Don't do this for integer types. There is only potential profit if
*** 1534,1569 ****
if (EliminateAutoBox && adr->is_AddP()) {
// The pointers in the autobox arrays are always non-null
Node* base = adr->in(AddPNode::Base);
if (base != NULL &&
!phase->type(base)->higher_equal(TypePtr::NULL_PTR)) {
! Compile::AliasType* atp = phase->C->alias_type(base->adr_type());
if (is_autobox_cache(atp)) {
return jt->join(TypePtr::NOTNULL)->is_ptr();
}
}
}
return jt;
}
}
} else if (tp->base() == Type::InstPtr) {
const TypeInstPtr* tinst = tp->is_instptr();
ciKlass* klass = tinst->klass();
assert( off != Type::OffsetBot ||
// arrays can be cast to Objects
tp->is_oopptr()->klass()->is_java_lang_Object() ||
// unsafe field access may not have a constant offset
! phase->C->has_unsafe_access(),
"Field accesses must be precise" );
// For oop loads, we expect the _type to be precise
! if (klass == phase->C->env()->String_klass() &&
adr->is_AddP() && off != Type::OffsetBot) {
// For constant Strings treat the final fields as compile time constants.
Node* base = adr->in(AddPNode::Base);
const TypeOopPtr* t = phase->type(base)->isa_oopptr();
if (t != NULL && t->singleton()) {
! ciField* field = phase->C->env()->String_klass()->get_field_by_offset(off, false);
if (field != NULL && field->is_final()) {
ciObject* string = t->const_oop();
ciConstant constant = string->as_instance()->field_value(field);
if (constant.basic_type() == T_INT) {
return TypeInt::make(constant.as_int());
--- 1535,1571 ----
if (EliminateAutoBox && adr->is_AddP()) {
// The pointers in the autobox arrays are always non-null
Node* base = adr->in(AddPNode::Base);
if (base != NULL &&
!phase->type(base)->higher_equal(TypePtr::NULL_PTR)) {
! Compile::AliasType* atp = C->alias_type(base->adr_type());
if (is_autobox_cache(atp)) {
return jt->join(TypePtr::NOTNULL)->is_ptr();
}
}
}
return jt;
}
}
} else if (tp->base() == Type::InstPtr) {
+ ciEnv* env = C->env();
const TypeInstPtr* tinst = tp->is_instptr();
ciKlass* klass = tinst->klass();
assert( off != Type::OffsetBot ||
// arrays can be cast to Objects
tp->is_oopptr()->klass()->is_java_lang_Object() ||
// 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
! if (klass == env->String_klass() &&
adr->is_AddP() && off != Type::OffsetBot) {
// For constant Strings treat the final fields as compile time constants.
Node* base = adr->in(AddPNode::Base);
const TypeOopPtr* t = phase->type(base)->isa_oopptr();
if (t != NULL && t->singleton()) {
! ciField* field = env->String_klass()->get_field_by_offset(off, false);
if (field != NULL && field->is_final()) {
ciObject* string = t->const_oop();
ciConstant constant = string->as_instance()->field_value(field);
if (constant.basic_type() == T_INT) {
return TypeInt::make(constant.as_int());
*** 1575,1584 ****
--- 1577,1612 ----
}
}
}
}
}
+ // Optimizations for constant objects
+ ciObject* const_oop = tinst->const_oop();
+ if (const_oop != NULL) {
+ // For constant CallSites treat the target field as a compile time constant.
+ if (const_oop->is_call_site()) {
+ ciCallSite* call_site = const_oop->as_call_site();
+ ciField* field = call_site->klass()->as_instance_klass()->get_field_by_offset(off, /*is_static=*/ false);
+ if (field != NULL && field->is_call_site_target()) {
+ ciMethodHandle* target = call_site->get_target();
+ if (target != NULL) { // just in case
+ ciConstant constant(T_OBJECT, target);
+ const Type* t;
+ if (adr->bottom_type()->is_ptr_to_narrowoop()) {
+ t = TypeNarrowOop::make_from_constant(constant.as_object(), true);
+ } else {
+ t = TypeOopPtr::make_from_constant(constant.as_object(), true);
+ }
+ // Add a dependence for invalidation of the optimization.
+ if (!call_site->is_constant_call_site()) {
+ C->dependencies()->assert_call_site_target_value(call_site, target);
+ }
+ return t;
+ }
+ }
+ }
+ }
} else if (tp->base() == Type::KlassPtr) {
assert( off != Type::OffsetBot ||
// arrays can be cast to Objects
tp->is_klassptr()->klass()->is_java_lang_Object() ||
// also allow array-loading from the primary supertype
src/share/vm/opto/memnode.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File