7071709: JSR 292: switchpoint invalidation should be pushed not pulled
Reviewed-by: never
This commit is contained in:
parent
db44acbeb4
commit
1038fed51d
@ -1493,6 +1493,7 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const {
|
|||||||
if (tp == NULL || tp->empty()) return Type::TOP;
|
if (tp == NULL || tp->empty()) return Type::TOP;
|
||||||
int off = tp->offset();
|
int off = tp->offset();
|
||||||
assert(off != Type::OffsetTop, "case covered by TypePtr::empty");
|
assert(off != Type::OffsetTop, "case covered by TypePtr::empty");
|
||||||
|
Compile* C = phase->C;
|
||||||
|
|
||||||
// Try to guess loaded type from pointer type
|
// Try to guess loaded type from pointer type
|
||||||
if (tp->base() == Type::AryPtr) {
|
if (tp->base() == Type::AryPtr) {
|
||||||
@ -1536,7 +1537,7 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const {
|
|||||||
Node* base = adr->in(AddPNode::Base);
|
Node* base = adr->in(AddPNode::Base);
|
||||||
if (base != NULL &&
|
if (base != NULL &&
|
||||||
!phase->type(base)->higher_equal(TypePtr::NULL_PTR)) {
|
!phase->type(base)->higher_equal(TypePtr::NULL_PTR)) {
|
||||||
Compile::AliasType* atp = phase->C->alias_type(base->adr_type());
|
Compile::AliasType* atp = C->alias_type(base->adr_type());
|
||||||
if (is_autobox_cache(atp)) {
|
if (is_autobox_cache(atp)) {
|
||||||
return jt->join(TypePtr::NOTNULL)->is_ptr();
|
return jt->join(TypePtr::NOTNULL)->is_ptr();
|
||||||
}
|
}
|
||||||
@ -1546,22 +1547,23 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (tp->base() == Type::InstPtr) {
|
} else if (tp->base() == Type::InstPtr) {
|
||||||
|
ciEnv* env = C->env();
|
||||||
const TypeInstPtr* tinst = tp->is_instptr();
|
const TypeInstPtr* tinst = tp->is_instptr();
|
||||||
ciKlass* klass = tinst->klass();
|
ciKlass* klass = tinst->klass();
|
||||||
assert( off != Type::OffsetBot ||
|
assert( off != Type::OffsetBot ||
|
||||||
// arrays can be cast to Objects
|
// arrays can be cast to Objects
|
||||||
tp->is_oopptr()->klass()->is_java_lang_Object() ||
|
tp->is_oopptr()->klass()->is_java_lang_Object() ||
|
||||||
// unsafe field access may not have a constant offset
|
// unsafe field access may not have a constant offset
|
||||||
phase->C->has_unsafe_access(),
|
C->has_unsafe_access(),
|
||||||
"Field accesses must be precise" );
|
"Field accesses must be precise" );
|
||||||
// For oop loads, we expect the _type to be precise
|
// For oop loads, we expect the _type to be precise
|
||||||
if (klass == phase->C->env()->String_klass() &&
|
if (klass == env->String_klass() &&
|
||||||
adr->is_AddP() && off != Type::OffsetBot) {
|
adr->is_AddP() && off != Type::OffsetBot) {
|
||||||
// For constant Strings treat the final fields as compile time constants.
|
// For constant Strings treat the final fields as compile time constants.
|
||||||
Node* base = adr->in(AddPNode::Base);
|
Node* base = adr->in(AddPNode::Base);
|
||||||
const TypeOopPtr* t = phase->type(base)->isa_oopptr();
|
const TypeOopPtr* t = phase->type(base)->isa_oopptr();
|
||||||
if (t != NULL && t->singleton()) {
|
if (t != NULL && t->singleton()) {
|
||||||
ciField* field = phase->C->env()->String_klass()->get_field_by_offset(off, false);
|
ciField* field = env->String_klass()->get_field_by_offset(off, false);
|
||||||
if (field != NULL && field->is_final()) {
|
if (field != NULL && field->is_final()) {
|
||||||
ciObject* string = t->const_oop();
|
ciObject* string = t->const_oop();
|
||||||
ciConstant constant = string->as_instance()->field_value(field);
|
ciConstant constant = string->as_instance()->field_value(field);
|
||||||
@ -1577,6 +1579,32 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 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) {
|
} else if (tp->base() == Type::KlassPtr) {
|
||||||
assert( off != Type::OffsetBot ||
|
assert( off != Type::OffsetBot ||
|
||||||
// arrays can be cast to Objects
|
// arrays can be cast to Objects
|
||||||
|
@ -147,19 +147,21 @@ void Parse::do_field_access(bool is_get, bool is_field) {
|
|||||||
void Parse::do_get_xxx(Node* obj, ciField* field, bool is_field) {
|
void Parse::do_get_xxx(Node* obj, ciField* field, bool is_field) {
|
||||||
// Does this field have a constant value? If so, just push the value.
|
// Does this field have a constant value? If so, just push the value.
|
||||||
if (field->is_constant()) {
|
if (field->is_constant()) {
|
||||||
|
// final field
|
||||||
if (field->is_static()) {
|
if (field->is_static()) {
|
||||||
// final static field
|
// final static field
|
||||||
if (push_constant(field->constant_value()))
|
if (push_constant(field->constant_value()))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// final non-static field of a trusted class (classes in
|
// final non-static field
|
||||||
// java.lang.invoke and sun.invoke packages and subpackages).
|
// Treat final non-static fields of trusted classes (classes in
|
||||||
|
// java.lang.invoke and sun.invoke packages and subpackages) as
|
||||||
|
// compile time constants.
|
||||||
if (obj->is_Con()) {
|
if (obj->is_Con()) {
|
||||||
const TypeOopPtr* oop_ptr = obj->bottom_type()->isa_oopptr();
|
const TypeOopPtr* oop_ptr = obj->bottom_type()->isa_oopptr();
|
||||||
ciObject* constant_oop = oop_ptr->const_oop();
|
ciObject* constant_oop = oop_ptr->const_oop();
|
||||||
ciConstant constant = field->constant_value_of(constant_oop);
|
ciConstant constant = field->constant_value_of(constant_oop);
|
||||||
|
|
||||||
if (push_constant(constant, true))
|
if (push_constant(constant, true))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user