mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-23 12:34:32 +02:00
8149813: Move trusted final field handling from C2 LoadNode::Value to shared code
Reviewed-by: thartmann, kvn
This commit is contained in:
parent
8555d89404
commit
03174f3030
4 changed files with 20 additions and 34 deletions
|
@ -211,6 +211,12 @@ static bool trust_final_non_static_fields(ciInstanceKlass* holder) {
|
|||
// so there is no hacking of finals going on with them.
|
||||
if (holder->is_anonymous())
|
||||
return true;
|
||||
// Trust final fields in all boxed classes
|
||||
if (holder->is_box_klass())
|
||||
return true;
|
||||
// Trust final fields in String
|
||||
if (holder->name() == ciSymbol::java_lang_String())
|
||||
return true;
|
||||
// Trust Atomic*FieldUpdaters: they are very important for performance, and make up one
|
||||
// more reason not to use Unsafe, if their final fields are trusted. See more in JDK-8140483.
|
||||
if (holder->name() == ciSymbol::java_util_concurrent_atomic_AtomicIntegerFieldUpdater_Impl() ||
|
||||
|
|
|
@ -1709,38 +1709,10 @@ const Type* LoadNode::Value(PhaseGVN* phase) const {
|
|||
// 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.
|
||||
// While we can list what field types java.lang.String has, it is more
|
||||
// future-proof to handle all possible field types, anticipating future
|
||||
// changes and experiments in String code.
|
||||
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);
|
||||
// Type::make_from_constant does not handle narrow oops, so handle it here.
|
||||
// Everything else can use the factory method.
|
||||
if ((constant.basic_type() == T_ARRAY || constant.basic_type() == T_OBJECT)
|
||||
&& adr->bottom_type()->is_ptr_to_narrowoop()) {
|
||||
return TypeNarrowOop::make_from_constant(constant.as_object(), true);
|
||||
} else {
|
||||
return Type::make_from_constant(constant, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// For oop loads, we expect the _type to be precise.
|
||||
// Optimizations for constant objects
|
||||
ciObject* const_oop = tinst->const_oop();
|
||||
if (const_oop != NULL) {
|
||||
// For constant Boxed value treat the target field as a compile time constant.
|
||||
if (tinst->is_ptr_to_boxed_value()) {
|
||||
return tinst->get_const_boxed_value();
|
||||
} else
|
||||
// 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();
|
||||
|
|
|
@ -1552,8 +1552,7 @@ Node* PhaseStringOpts::copy_string(GraphKit& kit, Node* str, Node* dst_array, No
|
|||
|
||||
if (str->is_Con()) {
|
||||
// Constant source string
|
||||
const TypeOopPtr* t = kit.gvn().type(src_array)->isa_oopptr();
|
||||
ciTypeArray* src_array_type = t->const_oop()->as_type_array();
|
||||
ciTypeArray* src_array_type = get_constant_value(kit, str);
|
||||
|
||||
// Check encoding of constant string
|
||||
bool src_is_byte = (get_constant_coder(kit, str) == java_lang_String::CODER_LATIN1);
|
||||
|
@ -1673,9 +1672,15 @@ jbyte PhaseStringOpts::get_constant_coder(GraphKit& kit, Node* str) {
|
|||
|
||||
int PhaseStringOpts::get_constant_length(GraphKit& kit, Node* str) {
|
||||
assert(str->is_Con(), "String must be constant");
|
||||
Node* src_array = kit.load_String_value(kit.control(), str);
|
||||
const TypeOopPtr* t = kit.gvn().type(src_array)->isa_oopptr();
|
||||
return t->const_oop()->as_type_array()->length();
|
||||
return get_constant_value(kit, str)->length();
|
||||
}
|
||||
|
||||
ciTypeArray* PhaseStringOpts::get_constant_value(GraphKit& kit, Node* str) {
|
||||
assert(str->is_Con(), "String must be constant");
|
||||
const TypeOopPtr* str_type = kit.gvn().type(str)->isa_oopptr();
|
||||
ciInstance* str_instance = str_type->const_oop()->as_instance();
|
||||
ciObject* src_array = str_instance->field_value_by_offset(java_lang_String::value_offset_in_bytes()).as_object();
|
||||
return src_array->as_type_array();
|
||||
}
|
||||
|
||||
void PhaseStringOpts::replace_string_concat(StringConcat* sc) {
|
||||
|
|
|
@ -97,6 +97,9 @@ class PhaseStringOpts : public Phase {
|
|||
// Returns the length of a constant string
|
||||
int get_constant_length(GraphKit& kit, Node* str);
|
||||
|
||||
// Returns the value array of a constant string
|
||||
ciTypeArray* get_constant_value(GraphKit& kit, Node* str);
|
||||
|
||||
// Clean up any leftover nodes
|
||||
void record_dead_node(Node* node);
|
||||
void remove_dead_nodes();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue