hotspot/src/share/vm/classfile/systemDictionary.cpp
// Update system dictionary - done after check_constraint and add_to_hierachy
// have been called.
void SystemDictionary::update_dictionary(int d_index, unsigned int d_hash,
int p_index, unsigned int p_hash,
instanceKlassHandle k,
Handle class_loader,
TRAPS) {
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
// Compile_lock prevents systemDictionary updates during compilations
assert_locked_or_safepoint(Compile_lock);
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
Symbol* name = k->name();
{- -------------------------------------------
(1) (以降の処理は SystemDictionary_lock で排他した状態で行う)
---------------------------------------- -}
{
MutexLocker mu1(SystemDictionary_lock, THREAD);
{- -------------------------------------------
(1) BiasedLocking が有効になっている場合は,
prototype header として biased locking pattern をセットしておく.
---------------------------------------- -}
// See whether biased locking is enabled and if so set it for this
// klass.
// Note that this must be done past the last potential blocking
// point / safepoint. We enable biased locking lazily using a
// VM_Operation to iterate the SystemDictionary and installing the
// biasable mark word into each instanceKlass's prototype header.
// To avoid race conditions where we accidentally miss enabling the
// optimization for one class in the process of being added to the
// dictionary, we must not safepoint after the test of
// BiasedLocking::enabled().
if (UseBiasedLocking && BiasedLocking::enabled()) {
// Set biased locking bit for all loaded classes; it will be
// cleared if revocation occurs too often for this type
// NOTE that we must only do this when the class is initally
// defined, not each time it is referenced from a new class loader
if (k->class_loader() == class_loader()) {
k->set_prototype_header(markOopDesc::biased_locking_prototype());
}
}
{- -------------------------------------------
(1) Dictionary::add_klass() を呼んで,
k 引数で指定されたクラスを SystemDictionary に登録する.
(なお, ついでに SystemDictionary::notice_modification() で変更回数をあげておく.
これは, コンパイル途中にメソッドが変更された場合に, 不正になってしまったコンパイル結果を破棄するために必要な処理.
(See: ciEnv::system_dictionary_modification_counter_changed()))
ただし, 既に処理対象のクラスが SystemDictionary に登録済みなら何もしない.
---------------------------------------- -}
// Check for a placeholder. If there, remove it and make a
// new system dictionary entry.
placeholders()->find_and_remove(p_index, p_hash, name, class_loader, THREAD);
klassOop sd_check = find_class(d_index, d_hash, name, class_loader);
if (sd_check == NULL) {
dictionary()->add_klass(name, class_loader, k);
notice_modification();
}
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
#ifdef ASSERT
sd_check = find_class(d_index, d_hash, name, class_loader);
assert (sd_check != NULL, "should have entry in system dictionary");
// Changed to allow PH to remain to complete class circularity checking
// while only one thread can define a class at one time, multiple
// classes can resolve the superclass for a class at one time,
// and the placeholder is used to track that
// Symbol* ph_check = find_placeholder(name, class_loader);
// assert (ph_check == NULL, "should not have a placeholder entry");
#endif
{- -------------------------------------------
(1)
---------------------------------------- -}
SystemDictionary_lock->notify_all();
}
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.