< prev index next >
src/hotspot/share/classfile/classLoaderData.cpp
Print this page
*** 80,94 ****
#endif // INCLUDE_ALL_GCS
#if INCLUDE_TRACE
#include "trace/tracing.hpp"
#endif
- // helper function to avoid in-line casts
- template <typename T> static T* load_ptr_acquire(T* volatile *p) {
- return static_cast<T*>(OrderAccess::load_ptr_acquire(p));
- }
-
ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL;
ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies) :
_class_loader(h_class_loader()),
_is_anonymous(is_anonymous),
--- 80,89 ----
*** 150,160 ****
}
oop* ClassLoaderData::ChunkedHandleList::add(oop o) {
if (_head == NULL || _head->_size == Chunk::CAPACITY) {
Chunk* next = new Chunk(_head);
! OrderAccess::release_store_ptr(&_head, next);
}
oop* handle = &_head->_data[_head->_size];
*handle = o;
OrderAccess::release_store(&_head->_size, _head->_size + 1);
return handle;
--- 145,155 ----
}
oop* ClassLoaderData::ChunkedHandleList::add(oop o) {
if (_head == NULL || _head->_size == Chunk::CAPACITY) {
Chunk* next = new Chunk(_head);
! OrderAccess::release_store(&_head, next);
}
oop* handle = &_head->_data[_head->_size];
*handle = o;
OrderAccess::release_store(&_head->_size, _head->_size + 1);
return handle;
*** 167,177 ****
}
}
}
void ClassLoaderData::ChunkedHandleList::oops_do(OopClosure* f) {
! Chunk* head = (Chunk*) OrderAccess::load_ptr_acquire(&_head);
if (head != NULL) {
// Must be careful when reading size of head
oops_do_chunk(f, head, OrderAccess::load_acquire(&head->_size));
for (Chunk* c = head->_next; c != NULL; c = c->_next) {
oops_do_chunk(f, c, c->_size);
--- 162,172 ----
}
}
}
void ClassLoaderData::ChunkedHandleList::oops_do(OopClosure* f) {
! Chunk* head = OrderAccess::load_acquire(&_head);
if (head != NULL) {
// Must be careful when reading size of head
oops_do_chunk(f, head, OrderAccess::load_acquire(&head->_size));
for (Chunk* c = head->_next; c != NULL; c = c->_next) {
oops_do_chunk(f, c, c->_size);
*** 255,301 ****
void ClassLoaderData::Dependencies::oops_do(OopClosure* f) {
f->do_oop((oop*)&_list_head);
}
void ClassLoaderData::classes_do(KlassClosure* klass_closure) {
! // Lock-free access requires load_ptr_acquire
! for (Klass* k = load_ptr_acquire(&_klasses); k != NULL; k = k->next_link()) {
klass_closure->do_klass(k);
assert(k != k->next_link(), "no loops!");
}
}
void ClassLoaderData::classes_do(void f(Klass * const)) {
! // Lock-free access requires load_ptr_acquire
! for (Klass* k = load_ptr_acquire(&_klasses); k != NULL; k = k->next_link()) {
f(k);
assert(k != k->next_link(), "no loops!");
}
}
void ClassLoaderData::methods_do(void f(Method*)) {
! // Lock-free access requires load_ptr_acquire
! for (Klass* k = load_ptr_acquire(&_klasses); k != NULL; k = k->next_link()) {
if (k->is_instance_klass() && InstanceKlass::cast(k)->is_loaded()) {
InstanceKlass::cast(k)->methods_do(f);
}
}
}
void ClassLoaderData::loaded_classes_do(KlassClosure* klass_closure) {
! // Lock-free access requires load_ptr_acquire
! for (Klass* k = load_ptr_acquire(&_klasses); k != NULL; k = k->next_link()) {
// Do not filter ArrayKlass oops here...
if (k->is_array_klass() || (k->is_instance_klass() && InstanceKlass::cast(k)->is_loaded())) {
klass_closure->do_klass(k);
}
}
}
void ClassLoaderData::classes_do(void f(InstanceKlass*)) {
! // Lock-free access requires load_ptr_acquire
! for (Klass* k = load_ptr_acquire(&_klasses); k != NULL; k = k->next_link()) {
if (k->is_instance_klass()) {
f(InstanceKlass::cast(k));
}
assert(k != k->next_link(), "no loops!");
}
--- 250,296 ----
void ClassLoaderData::Dependencies::oops_do(OopClosure* f) {
f->do_oop((oop*)&_list_head);
}
void ClassLoaderData::classes_do(KlassClosure* klass_closure) {
! // Lock-free access requires load_acquire
! for (Klass* k = OrderAccess::load_acquire(&_klasses); k != NULL; k = k->next_link()) {
klass_closure->do_klass(k);
assert(k != k->next_link(), "no loops!");
}
}
void ClassLoaderData::classes_do(void f(Klass * const)) {
! // Lock-free access requires load_acquire
! for (Klass* k = OrderAccess::load_acquire(&_klasses); k != NULL; k = k->next_link()) {
f(k);
assert(k != k->next_link(), "no loops!");
}
}
void ClassLoaderData::methods_do(void f(Method*)) {
! // Lock-free access requires load_acquire
! for (Klass* k = OrderAccess::load_acquire(&_klasses); k != NULL; k = k->next_link()) {
if (k->is_instance_klass() && InstanceKlass::cast(k)->is_loaded()) {
InstanceKlass::cast(k)->methods_do(f);
}
}
}
void ClassLoaderData::loaded_classes_do(KlassClosure* klass_closure) {
! // Lock-free access requires load_acquire
! for (Klass* k = OrderAccess::load_acquire(&_klasses); k != NULL; k = k->next_link()) {
// Do not filter ArrayKlass oops here...
if (k->is_array_klass() || (k->is_instance_klass() && InstanceKlass::cast(k)->is_loaded())) {
klass_closure->do_klass(k);
}
}
}
void ClassLoaderData::classes_do(void f(InstanceKlass*)) {
! // Lock-free access requires load_acquire
! for (Klass* k = OrderAccess::load_acquire(&_klasses); k != NULL; k = k->next_link()) {
if (k->is_instance_klass()) {
f(InstanceKlass::cast(k));
}
assert(k != k->next_link(), "no loops!");
}
*** 447,457 ****
MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag);
Klass* old_value = _klasses;
k->set_next_link(old_value);
// Link the new item into the list, making sure the linked class is stable
// since the list can be walked without a lock
! OrderAccess::release_store_ptr(&_klasses, k);
}
if (publicize && k->class_loader_data() != NULL) {
ResourceMark rm;
log_trace(class, loader, data)("Adding k: " PTR_FORMAT " %s to CLD: "
--- 442,452 ----
MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag);
Klass* old_value = _klasses;
k->set_next_link(old_value);
// Link the new item into the list, making sure the linked class is stable
// since the list can be walked without a lock
! OrderAccess::release_store(&_klasses, k);
}
if (publicize && k->class_loader_data() != NULL) {
ResourceMark rm;
log_trace(class, loader, data)("Adding k: " PTR_FORMAT " %s to CLD: "
*** 587,608 ****
static_klass_iterator.adjust_saved_class(this);
}
ModuleEntryTable* ClassLoaderData::modules() {
// Lazily create the module entry table at first request.
! // Lock-free access requires load_ptr_acquire.
! ModuleEntryTable* modules = load_ptr_acquire(&_modules);
if (modules == NULL) {
MutexLocker m1(Module_lock);
// Check if _modules got allocated while we were waiting for this lock.
if ((modules = _modules) == NULL) {
modules = new ModuleEntryTable(ModuleEntryTable::_moduletable_entry_size);
{
MutexLockerEx m1(metaspace_lock(), Mutex::_no_safepoint_check_flag);
// Ensure _modules is stable, since it is examined without a lock
! OrderAccess::release_store_ptr(&_modules, modules);
}
}
}
return modules;
}
--- 582,603 ----
static_klass_iterator.adjust_saved_class(this);
}
ModuleEntryTable* ClassLoaderData::modules() {
// Lazily create the module entry table at first request.
! // Lock-free access requires load_acquire.
! ModuleEntryTable* modules = OrderAccess::load_acquire(&_modules);
if (modules == NULL) {
MutexLocker m1(Module_lock);
// Check if _modules got allocated while we were waiting for this lock.
if ((modules = _modules) == NULL) {
modules = new ModuleEntryTable(ModuleEntryTable::_moduletable_entry_size);
{
MutexLockerEx m1(metaspace_lock(), Mutex::_no_safepoint_check_flag);
// Ensure _modules is stable, since it is examined without a lock
! OrderAccess::release_store(&_modules, modules);
}
}
}
return modules;
}
*** 735,746 ****
Metaspace* ClassLoaderData::metaspace_non_null() {
// If the metaspace has not been allocated, create a new one. Might want
// to create smaller arena for Reflection class loaders also.
// The reason for the delayed allocation is because some class loaders are
// simply for delegating with no metadata of their own.
! // Lock-free access requires load_ptr_acquire.
! Metaspace* metaspace = load_ptr_acquire(&_metaspace);
if (metaspace == NULL) {
MutexLockerEx ml(_metaspace_lock, Mutex::_no_safepoint_check_flag);
// Check if _metaspace got allocated while we were waiting for this lock.
if ((metaspace = _metaspace) == NULL) {
if (this == the_null_class_loader_data()) {
--- 730,741 ----
Metaspace* ClassLoaderData::metaspace_non_null() {
// If the metaspace has not been allocated, create a new one. Might want
// to create smaller arena for Reflection class loaders also.
// The reason for the delayed allocation is because some class loaders are
// simply for delegating with no metadata of their own.
! // Lock-free access requires load_acquire.
! Metaspace* metaspace = OrderAccess::load_acquire(&_metaspace);
if (metaspace == NULL) {
MutexLockerEx ml(_metaspace_lock, Mutex::_no_safepoint_check_flag);
// Check if _metaspace got allocated while we were waiting for this lock.
if ((metaspace = _metaspace) == NULL) {
if (this == the_null_class_loader_data()) {
*** 758,768 ****
metaspace = new Metaspace(_metaspace_lock, Metaspace::ReflectionMetaspaceType);
} else {
metaspace = new Metaspace(_metaspace_lock, Metaspace::StandardMetaspaceType);
}
// Ensure _metaspace is stable, since it is examined without a lock
! OrderAccess::release_store_ptr(&_metaspace, metaspace);
}
}
return metaspace;
}
--- 753,763 ----
metaspace = new Metaspace(_metaspace_lock, Metaspace::ReflectionMetaspaceType);
} else {
metaspace = new Metaspace(_metaspace_lock, Metaspace::StandardMetaspaceType);
}
// Ensure _metaspace is stable, since it is examined without a lock
! OrderAccess::release_store(&_metaspace, metaspace);
}
}
return metaspace;
}
*** 912,923 ****
assert(k != k->next_link(), "no loops!");
}
}
bool ClassLoaderData::contains_klass(Klass* klass) {
! // Lock-free access requires load_ptr_acquire
! for (Klass* k = load_ptr_acquire(&_klasses); k != NULL; k = k->next_link()) {
if (k == klass) return true;
}
return false;
}
--- 907,918 ----
assert(k != k->next_link(), "no loops!");
}
}
bool ClassLoaderData::contains_klass(Klass* klass) {
! // Lock-free access requires load_acquire
! for (Klass* k = OrderAccess::load_acquire(&_klasses); k != NULL; k = k->next_link()) {
if (k == klass) return true;
}
return false;
}
*** 946,956 ****
if (!is_anonymous) {
ClassLoaderData** cld_addr = java_lang_ClassLoader::loader_data_addr(loader());
// First, Atomically set it
! ClassLoaderData* old = (ClassLoaderData*) Atomic::cmpxchg_ptr(cld, cld_addr, NULL);
if (old != NULL) {
delete cld;
// Returns the data.
return old;
}
--- 941,951 ----
if (!is_anonymous) {
ClassLoaderData** cld_addr = java_lang_ClassLoader::loader_data_addr(loader());
// First, Atomically set it
! ClassLoaderData* old = Atomic::cmpxchg(cld, cld_addr, (ClassLoaderData*)NULL);
if (old != NULL) {
delete cld;
// Returns the data.
return old;
}
*** 961,971 ****
ClassLoaderData** list_head = &_head;
ClassLoaderData* next = _head;
do {
cld->set_next(next);
! ClassLoaderData* exchanged = (ClassLoaderData*)Atomic::cmpxchg_ptr(cld, list_head, next);
if (exchanged == next) {
LogTarget(Debug, class, loader, data) lt;
if (lt.is_enabled()) {
PauseNoSafepointVerifier pnsv(&no_safepoints); // Need safe points for JavaCalls::call_virtual
LogStream ls(lt);
--- 956,966 ----
ClassLoaderData** list_head = &_head;
ClassLoaderData* next = _head;
do {
cld->set_next(next);
! ClassLoaderData* exchanged = Atomic::cmpxchg(cld, list_head, next);
if (exchanged == next) {
LogTarget(Debug, class, loader, data) lt;
if (lt.is_enabled()) {
PauseNoSafepointVerifier pnsv(&no_safepoints); // Need safe points for JavaCalls::call_virtual
LogStream ls(lt);
*** 1385,1395 ****
Klass* head = _next_klass;
while (head != NULL) {
Klass* next = next_klass_in_cldg(head);
! Klass* old_head = (Klass*)Atomic::cmpxchg_ptr(next, &_next_klass, head);
if (old_head == head) {
return head; // Won the CAS.
}
--- 1380,1390 ----
Klass* head = _next_klass;
while (head != NULL) {
Klass* next = next_klass_in_cldg(head);
! Klass* old_head = Atomic::cmpxchg(next, &_next_klass, head);
if (old_head == head) {
return head; // Won the CAS.
}
< prev index next >