8223216: C2: Unify class initialization checks between new, getstatic, and putstatic

Reviewed-by: kvn, dlong
This commit is contained in:
Vladimir Ivanov 2019-05-30 19:12:11 +03:00
parent 8ac3b68688
commit 5db82de14b
9 changed files with 125 additions and 115 deletions

View file

@ -3846,9 +3846,42 @@ void Compile::set_allowed_deopt_reasons() {
}
}
bool Compile::is_compiling_clinit_for(ciKlass* k) {
ciMethod* root = method(); // the root method of compilation
return root->is_static_initializer() && root->holder() == k; // access in the context of clinit
bool Compile::needs_clinit_barrier(ciMethod* method, ciMethod* accessing_method) {
return method->is_static() && needs_clinit_barrier(method->holder(), accessing_method);
}
bool Compile::needs_clinit_barrier(ciField* field, ciMethod* accessing_method) {
return field->is_static() && needs_clinit_barrier(field->holder(), accessing_method);
}
bool Compile::needs_clinit_barrier(ciInstanceKlass* holder, ciMethod* accessing_method) {
if (holder->is_initialized()) {
return false;
}
if (holder->is_being_initialized()) {
if (accessing_method->holder() == holder) {
// Access inside a class. The barrier can be elided when access happens in <clinit>,
// <init>, or a static method. In all those cases, there was an initialization
// barrier on the holder klass passed.
if (accessing_method->is_static_initializer() ||
accessing_method->is_object_initializer() ||
accessing_method->is_static()) {
return false;
}
} else if (accessing_method->holder()->is_subclass_of(holder)) {
// Access from a subclass. The barrier can be elided only when access happens in <clinit>.
// In case of <init> or a static method, the barrier is on the subclass is not enough:
// child class can become fully initialized while its parent class is still being initialized.
if (accessing_method->is_static_initializer()) {
return false;
}
}
ciMethod* root = method(); // the root method of compilation
if (root != accessing_method) {
return needs_clinit_barrier(holder, root); // check access in the context of compilation root
}
}
return true;
}
#ifndef PRODUCT