Skip to content

Commit

Permalink
8251945: SIGSEGV in PackageEntry::purge_qualified_exports()
Browse files Browse the repository at this point in the history
Reviewed-by: adinn
  • Loading branch information
zhengyu123 committed Jun 21, 2021
1 parent cbe9c1b commit 3c54e03
Show file tree
Hide file tree
Showing 12 changed files with 253 additions and 39 deletions.
26 changes: 14 additions & 12 deletions src/hotspot/share/classfile/classLoaderData.cpp
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -1041,22 +1041,24 @@ bool ClassLoaderDataGraph::_metaspace_oom = false;
// Add a new class loader data node to the list. Assign the newly created
// ClassLoaderData into the java/lang/ClassLoader object as a hidden field
ClassLoaderData* ClassLoaderDataGraph::add_to_graph(Handle loader, bool is_anonymous) {
NoSafepointVerifier no_safepoints; // we mustn't GC until we've installed the
// ClassLoaderData in the graph since the CLD
// contains oops in _handles that must be walked.

ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous);
ClassLoaderData* cld;

if (!is_anonymous) {
// First, Atomically set it
ClassLoaderData* old = java_lang_ClassLoader::cmpxchg_loader_data(cld, loader(), NULL);
if (old != NULL) {
delete cld;
// Returns the data.
return old;
MutexLocker ml(ClassLoaderDataGraph_lock);
cld = java_lang_ClassLoader::loader_data_raw(loader());
if (cld != NULL) {
return cld;
}
cld = new ClassLoaderData(loader, is_anonymous);
java_lang_ClassLoader::release_set_loader_data(loader(), cld);
} else {
cld = new ClassLoaderData(loader, is_anonymous);
}

NoSafepointVerifier no_safepoints; // we mustn't GC until we've installed the
// ClassLoaderData in the graph since the CLD
// contains oops in _handles that must be walked.

// We won the race, and therefore the task of adding the data to the list of
// class loader data
ClassLoaderData** list_head = &_head;
Expand Down
6 changes: 3 additions & 3 deletions src/hotspot/share/classfile/classLoaderData.inline.hpp
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -45,7 +45,7 @@ inline ClassLoaderData* ClassLoaderData::class_loader_data_or_null(oop loader) {
if (loader == NULL) {
return ClassLoaderData::the_null_class_loader_data();
}
return java_lang_ClassLoader::loader_data(loader);
return java_lang_ClassLoader::loader_data_acquire(loader);
}

inline ClassLoaderData* ClassLoaderData::class_loader_data(oop loader) {
Expand All @@ -59,7 +59,7 @@ inline ClassLoaderData *ClassLoaderDataGraph::find_or_create(Handle loader) {
guarantee(loader() != NULL && oopDesc::is_oop(loader()), "Loader must be oop");
// Gets the class loader data out of the java/lang/ClassLoader object, if non-null
// it's already in the loader_data, so no need to add
ClassLoaderData* loader_data= java_lang_ClassLoader::loader_data(loader());
ClassLoaderData* loader_data= java_lang_ClassLoader::loader_data_acquire(loader());
if (loader_data) {
return loader_data;
}
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/share/classfile/classLoaderStats.cpp
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -139,7 +139,7 @@ void ClassLoaderStatsClosure::print() {


void ClassLoaderStatsClosure::addEmptyParents(oop cl) {
while (cl != NULL && java_lang_ClassLoader::loader_data(cl) == NULL) {
while (cl != NULL && java_lang_ClassLoader::loader_data_acquire(cl) == NULL) {
// This classloader has not loaded any classes
ClassLoaderStats** cls_ptr = _stats->get(cl);
if (cls_ptr == NULL) {
Expand Down
16 changes: 11 additions & 5 deletions src/hotspot/share/classfile/javaClasses.cpp
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -4020,14 +4020,20 @@ int java_lang_ClassLoader::name_offset = -1;
int java_lang_ClassLoader::nameAndId_offset = -1;
int java_lang_ClassLoader::unnamedModule_offset = -1;

ClassLoaderData* java_lang_ClassLoader::loader_data(oop loader) {
ClassLoaderData* java_lang_ClassLoader::loader_data_acquire(oop loader) {
assert(loader != NULL && oopDesc::is_oop(loader), "loader must be oop");
return HeapAccess<>::load_at(loader, _loader_data_offset);
return HeapAccess<MO_ACQUIRE>::load_at(loader, _loader_data_offset);
}

ClassLoaderData* java_lang_ClassLoader::cmpxchg_loader_data(ClassLoaderData* new_data, oop loader, ClassLoaderData* expected_data) {
ClassLoaderData* java_lang_ClassLoader::loader_data_raw(oop loader) {
assert(loader != NULL && oopDesc::is_oop(loader), "loader must be oop");
return HeapAccess<>::atomic_cmpxchg_at(new_data, loader, _loader_data_offset, expected_data);
return RawAccess<>::load_at(loader, _loader_data_offset);
}

void java_lang_ClassLoader::release_set_loader_data(oop loader, ClassLoaderData* new_data) {
assert(loader != NULL, "loader must not be NULL");
assert(oopDesc::is_oop(loader), "loader must be oop");
HeapAccess<MO_RELEASE>::store_at(loader, _loader_data_offset, new_data);
}

#define CLASSLOADER_FIELDS_DO(macro) \
Expand Down
7 changes: 4 additions & 3 deletions src/hotspot/share/classfile/javaClasses.hpp
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -1320,8 +1320,9 @@ class java_lang_ClassLoader : AllStatic {
static void compute_offsets();
static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

static ClassLoaderData* loader_data(oop loader);
static ClassLoaderData* cmpxchg_loader_data(ClassLoaderData* new_data, oop loader, ClassLoaderData* expected_data);
static ClassLoaderData* loader_data_acquire(oop loader);
static ClassLoaderData* loader_data_raw(oop loader);
static void release_set_loader_data(oop loader, ClassLoaderData* new_data);

static oop parent(oop loader);
static oop name(oop loader);
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/share/gc/parallel/psCompactionManager.cpp
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -183,7 +183,7 @@ void InstanceMirrorKlass::oop_pc_follow_contents(oop obj, ParCompactionManager*
void InstanceClassLoaderKlass::oop_pc_follow_contents(oop obj, ParCompactionManager* cm) {
InstanceKlass::oop_pc_follow_contents(obj, cm);

ClassLoaderData * const loader_data = java_lang_ClassLoader::loader_data(obj);
ClassLoaderData * const loader_data = java_lang_ClassLoader::loader_data_acquire(obj);
if (loader_data != NULL) {
cm->follow_class_loader(loader_data);
}
Expand Down
6 changes: 3 additions & 3 deletions src/hotspot/share/jfr/periodic/jfrPeriodic.cpp
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -468,9 +468,9 @@ class JfrClassLoaderStatsClosure : public ClassLoaderStatsClosure {

bool do_entry(oop const& key, ClassLoaderStats* const& cls) {
const ClassLoaderData* this_cld = cls->_class_loader != NULL ?
java_lang_ClassLoader::loader_data(cls->_class_loader) : (ClassLoaderData*)NULL;
java_lang_ClassLoader::loader_data_acquire(cls->_class_loader) : (ClassLoaderData*)NULL;
const ClassLoaderData* parent_cld = cls->_parent != NULL ?
java_lang_ClassLoader::loader_data(cls->_parent) : (ClassLoaderData*)NULL;
java_lang_ClassLoader::loader_data_acquire(cls->_parent) : (ClassLoaderData*)NULL;
EventClassLoaderStatistics event;
event.set_classLoader(this_cld);
event.set_parentClassLoader(parent_cld);
Expand Down
6 changes: 3 additions & 3 deletions src/hotspot/share/oops/instanceClassLoaderKlass.inline.hpp
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -39,7 +39,7 @@ inline void InstanceClassLoaderKlass::oop_oop_iterate(oop obj, OopClosureType* c
InstanceKlass::oop_oop_iterate<T>(obj, closure);

if (Devirtualizer::do_metadata(closure)) {
ClassLoaderData* cld = java_lang_ClassLoader::loader_data(obj);
ClassLoaderData* cld = java_lang_ClassLoader::loader_data_acquire(obj);
// cld can be null if we have a non-registered class loader.
if (cld != NULL) {
Devirtualizer::do_cld(closure, cld);
Expand All @@ -61,7 +61,7 @@ inline void InstanceClassLoaderKlass::oop_oop_iterate_bounded(oop obj, OopClosur

if (Devirtualizer::do_metadata(closure)) {
if (mr.contains(obj)) {
ClassLoaderData* cld = java_lang_ClassLoader::loader_data(obj);
ClassLoaderData* cld = java_lang_ClassLoader::loader_data_acquire(obj);
// cld can be null if we have a non-registered class loader.
if (cld != NULL) {
Devirtualizer::do_cld(closure, cld);
Expand Down
6 changes: 3 additions & 3 deletions src/hotspot/share/prims/whitebox.cpp
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -1550,7 +1550,7 @@ WB_ENTRY(jlong, WB_AllocateMetaspace(JNIEnv* env, jobject wb, jobject class_load

oop class_loader_oop = JNIHandles::resolve(class_loader);
ClassLoaderData* cld = class_loader_oop != NULL
? java_lang_ClassLoader::loader_data(class_loader_oop)
? java_lang_ClassLoader::loader_data_acquire(class_loader_oop)
: ClassLoaderData::the_null_class_loader_data();

void* metadata = MetadataFactory::new_array<u1>(cld, WhiteBox::array_bytes_to_length((size_t)size), thread);
Expand All @@ -1561,7 +1561,7 @@ WB_END
WB_ENTRY(void, WB_FreeMetaspace(JNIEnv* env, jobject wb, jobject class_loader, jlong addr, jlong size))
oop class_loader_oop = JNIHandles::resolve(class_loader);
ClassLoaderData* cld = class_loader_oop != NULL
? java_lang_ClassLoader::loader_data(class_loader_oop)
? java_lang_ClassLoader::loader_data_acquire(class_loader_oop)
: ClassLoaderData::the_null_class_loader_data();

MetadataFactory::free_array(cld, (Array<u1>*)(uintptr_t)addr);
Expand Down
4 changes: 3 additions & 1 deletion src/hotspot/share/runtime/mutexLocker.cpp
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -148,6 +148,7 @@ Mutex* UnsafeJlong_lock = NULL;
Monitor* CodeHeapStateAnalytics_lock = NULL;

Mutex* MetaspaceExpand_lock = NULL;
Mutex* ClassLoaderDataGraph_lock = NULL;
Mutex* ThreadIdTableCreate_lock = NULL;
Monitor* ThreadsSMRDelete_lock = NULL;
Mutex* SharedDecoder_lock = NULL;
Expand Down Expand Up @@ -239,6 +240,7 @@ void mutex_init() {
def(OopMapCacheAlloc_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_always); // used for oop_map_cache allocation.

def(MetaspaceExpand_lock , PaddedMutex , leaf-1, true, Monitor::_safepoint_check_never);
def(ClassLoaderDataGraph_lock , PaddedMutex , nonleaf, true, Monitor::_safepoint_check_always);

def(Patching_lock , PaddedMutex , special, true, Monitor::_safepoint_check_never); // used for safepointing and code patching.
def(Service_lock , PaddedMonitor, special, true, Monitor::_safepoint_check_never); // used for service thread operations
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/share/runtime/mutexLocker.hpp
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -151,7 +151,7 @@ extern Mutex* UnsafeJlong_lock; // provides Unsafe atomic updat
#endif

extern Mutex* MetaspaceExpand_lock; // protects Metaspace virtualspace and chunk expansions

extern Mutex* ClassLoaderDataGraph_lock; // protects CLDG list, needed for concurrent unloading

extern Monitor* CodeHeapStateAnalytics_lock; // lock print functions against concurrent analyze functions.
// Only used locally in PrintCodeCacheLayout processing.
Expand Down

1 comment on commit 3c54e03

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.