< prev index next > src/hotspot/share/oops/instanceKlass.cpp
Print this page
assert(lock != nullptr || !is_not_initialized(), // initialized or in_error state
"only fully initialized state can have a null lock");
return lock;
}
! // Set the initialization lock to null so the object can be GC'ed. Any racing
// threads to get this lock will see a null lock and will not lock.
// That's okay because they all check for initialized state after getting
! // the lock and return.
void InstanceKlass::fence_and_clear_init_lock() {
// make sure previous stores are all done, notably the init_state.
OrderAccess::storestore();
java_lang_Class::clear_init_lock(java_mirror());
assert(!is_not_initialized(), "class must be initialized now");
}
// See "The Virtual Machine Specification" section 2.16.5 for a detailed explanation of the class initialization
// process. The step comments refers to the procedure described in that section.
// Note: implementation moved to static method to expose the this pointer.
void InstanceKlass::initialize(TRAPS) {
assert(lock != nullptr || !is_not_initialized(), // initialized or in_error state
"only fully initialized state can have a null lock");
return lock;
}
! // Set the initialization lock to null so the object can be GC'ed. Any racing
// threads to get this lock will see a null lock and will not lock.
// That's okay because they all check for initialized state after getting
! // the lock and return. For preempted vthreads we keep the oop protected
+ // in the ObjectMonitor (see ObjectMonitor::set_object_strong()).
void InstanceKlass::fence_and_clear_init_lock() {
// make sure previous stores are all done, notably the init_state.
OrderAccess::storestore();
java_lang_Class::clear_init_lock(java_mirror());
assert(!is_not_initialized(), "class must be initialized now");
}
+ void InstanceKlass::initialize_preemptable(TRAPS) {
+ if (this->should_be_initialized()) {
+ PREEMPT_ON_INIT_SUPPORTED_ONLY(PreemptableInitCall pic(THREAD, this);)
+ initialize_impl(THREAD);
+ } else {
+ assert(is_initialized(), "sanity check");
+ }
+ }
// See "The Virtual Machine Specification" section 2.16.5 for a detailed explanation of the class initialization
// process. The step comments refers to the procedure described in that section.
// Note: implementation moved to static method to expose the this pointer.
void InstanceKlass::initialize(TRAPS) {
// verification & rewriting
{
HandleMark hm(THREAD);
Handle h_init_lock(THREAD, init_lock());
! ObjectLocker ol(h_init_lock, jt);
// rewritten will have been set if loader constraint error found
// on an earlier link attempt
// don't verify or rewrite if already rewritten
//
// verification & rewriting
{
HandleMark hm(THREAD);
Handle h_init_lock(THREAD, init_lock());
! ObjectLocker ol(h_init_lock, CHECK_PREEMPTABLE_false);
+ // Don't allow preemption if we link/initialize classes below,
+ // since that would release this monitor while we are in the
+ // middle of linking this class.
+ NoPreemptMark npm(THREAD);
+
// rewritten will have been set if loader constraint error found
// on an earlier link attempt
// don't verify or rewrite if already rewritten
//
// refer to the JVM book page 47 for description of steps
// Step 1
{
Handle h_init_lock(THREAD, init_lock());
! ObjectLocker ol(h_init_lock, jt);
// Step 2
// If we were to use wait() instead of waitInterruptibly() then
// we might end up throwing IE from link/symbol resolution sites
// that aren't expected to throw. This would wreak havoc. See 6320309.
// refer to the JVM book page 47 for description of steps
// Step 1
{
Handle h_init_lock(THREAD, init_lock());
! ObjectLocker ol(h_init_lock, CHECK_PREEMPTABLE);
// Step 2
// If we were to use wait() instead of waitInterruptibly() then
// we might end up throwing IE from link/symbol resolution sites
// that aren't expected to throw. This would wreak havoc. See 6320309.
ResourceMark rm(jt);
log_debug(class, init)("Thread \"%s\" waiting for initialization of %s by thread \"%s\"",
jt->name(), external_name(), init_thread_name());
}
wait = true;
! jt->set_class_to_be_initialized(this);
! ol.wait_uninterruptibly(jt);
- jt->set_class_to_be_initialized(nullptr);
}
// Step 3
if (is_being_initialized() && is_reentrant_initialization(jt)) {
if (debug_logging_enabled) {
ResourceMark rm(jt);
log_debug(class, init)("Thread \"%s\" waiting for initialization of %s by thread \"%s\"",
jt->name(), external_name(), init_thread_name());
}
wait = true;
! ThreadWaitingForClassInit twcl(THREAD, this);
! ol.wait_uninterruptibly(CHECK_PREEMPTABLE);
}
// Step 3
if (is_being_initialized() && is_reentrant_initialization(jt)) {
if (debug_logging_enabled) {
jt->name(), external_name());
}
}
}
+ // Block preemption once we are the initializer thread. Unmounting now
+ // would complicate the reentrant case (identity is platform thread).
+ NoPreemptMark npm(THREAD);
+
// Step 7
// Next, if C is a class rather than an interface, initialize it's super class and super
// interfaces.
if (!is_interface()) {
Klass* super_klass = super();
< prev index next >